From 83605debe0a6b3a53b339f24992c9a54511d2a28 Mon Sep 17 00:00:00 2001 From: HÃ¥vard Pettersen Date: Wed, 24 Mar 2021 14:56:45 +0000 Subject: handle value decoding failures more gracefully --- .../tests/eval/value_codec/value_codec_test.cpp | 12 ++++++------ eval/src/vespa/eval/eval/value_codec.cpp | 22 +++++++++++++++------- eval/src/vespa/eval/eval/value_codec.h | 5 +++++ 3 files changed, 26 insertions(+), 13 deletions(-) (limited to 'eval/src') diff --git a/eval/src/tests/eval/value_codec/value_codec_test.cpp b/eval/src/tests/eval/value_codec/value_codec_test.cpp index 0bb1bcfb337..99afba4aed9 100644 --- a/eval/src/tests/eval/value_codec/value_codec_test.cpp +++ b/eval/src/tests/eval/value_codec/value_codec_test.cpp @@ -335,11 +335,11 @@ TEST(ValueCodecTest, bad_sparse_tensors_are_caught) { bad.encode_default(data_default); bad.encode_with_double(data_double); bad.encode_with_float(data_float); - VESPA_EXPECT_EXCEPTION(decode_value(data_default, factory), vespalib::IllegalStateException, + VESPA_EXPECT_EXCEPTION(decode_value(data_default, factory), vespalib::eval::DecodeValueException, "serialized input claims 12345678 blocks of size 1*8, but only"); - VESPA_EXPECT_EXCEPTION(decode_value(data_double, factory), vespalib::IllegalStateException, + VESPA_EXPECT_EXCEPTION(decode_value(data_double, factory), vespalib::eval::DecodeValueException, "serialized input claims 12345678 blocks of size 1*8, but only"); - VESPA_EXPECT_EXCEPTION(decode_value(data_float, factory), vespalib::IllegalStateException, + VESPA_EXPECT_EXCEPTION(decode_value(data_float, factory), vespalib::eval::DecodeValueException, "serialized input claims 12345678 blocks of size 1*4, but only"); } @@ -388,11 +388,11 @@ TEST(ValueCodecTest, bad_dense_tensors_are_caught) { bad.encode_default(data_default); bad.encode_with_double(data_double); bad.encode_with_float(data_float); - VESPA_EXPECT_EXCEPTION(decode_value(data_default, factory), vespalib::IllegalStateException, + VESPA_EXPECT_EXCEPTION(decode_value(data_default, factory), vespalib::eval::DecodeValueException, "serialized input claims 1 blocks of size 60000*8, but only"); - VESPA_EXPECT_EXCEPTION(decode_value(data_double, factory), vespalib::IllegalStateException, + VESPA_EXPECT_EXCEPTION(decode_value(data_double, factory), vespalib::eval::DecodeValueException, "serialized input claims 1 blocks of size 60000*8, but only"); - VESPA_EXPECT_EXCEPTION(decode_value(data_float, factory), vespalib::IllegalStateException, + VESPA_EXPECT_EXCEPTION(decode_value(data_float, factory), vespalib::eval::DecodeValueException, "serialized input claims 1 blocks of size 60000*4, but only"); } diff --git a/eval/src/vespa/eval/eval/value_codec.cpp b/eval/src/vespa/eval/eval/value_codec.cpp index bf45f34fd64..85feadca85e 100644 --- a/eval/src/vespa/eval/eval/value_codec.cpp +++ b/eval/src/vespa/eval/eval/value_codec.cpp @@ -14,6 +14,8 @@ using vespalib::make_string_short::fmt; namespace vespalib::eval { +VESPA_IMPLEMENT_EXCEPTION(DecodeValueException, Exception); + namespace { constexpr uint32_t DOUBLE_CELL_TYPE = 0; @@ -308,13 +310,19 @@ void encode_value(const Value &value, nbostream &output) { } std::unique_ptr decode_value(nbostream &input, const ValueBuilderFactory &factory) { - Format format(input.getInt1_4Bytes()); - ValueType type = decode_type(input, format); - size_t num_mapped_dims = type.count_mapped_dimensions(); - size_t dense_subspace_size = type.dense_subspace_size(); - const size_t num_blocks = maybe_decode_num_blocks(input, (num_mapped_dims > 0), format); - DecodeState state{type, dense_subspace_size, num_blocks, num_mapped_dims}; - return typify_invoke<1,TypifyCellType,ContentDecoder>(type.cell_type(), input, state, factory); + try { + Format format(input.getInt1_4Bytes()); + ValueType type = decode_type(input, format); + size_t num_mapped_dims = type.count_mapped_dimensions(); + size_t dense_subspace_size = type.dense_subspace_size(); + const size_t num_blocks = maybe_decode_num_blocks(input, (num_mapped_dims > 0), format); + DecodeState state{type, dense_subspace_size, num_blocks, num_mapped_dims}; + return typify_invoke<1,TypifyCellType,ContentDecoder>(type.cell_type(), input, state, factory); + } catch (const OOMException &) { + throw; + } catch (const Exception &e) { + throw DecodeValueException("failed to decode value", e); + } } //----------------------------------------------------------------------------- diff --git a/eval/src/vespa/eval/eval/value_codec.h b/eval/src/vespa/eval/eval/value_codec.h index 058b2d7bf4f..23eb2de8e41 100644 --- a/eval/src/vespa/eval/eval/value_codec.h +++ b/eval/src/vespa/eval/eval/value_codec.h @@ -5,11 +5,14 @@ #include "value.h" #include "tensor_spec.h" #include +#include namespace vespalib { class nbostream; } namespace vespalib::eval { +VESPA_DEFINE_EXCEPTION(DecodeValueException, Exception); + /** * encode a value (which must support the new APIs) to binary format **/ @@ -17,6 +20,8 @@ void encode_value(const Value &value, nbostream &output); /** * decode a value from binary format + * + * will throw DecodeValueException if input contains malformed data **/ std::unique_ptr decode_value(nbostream &input, const ValueBuilderFactory &factory); -- cgit v1.2.3