summaryrefslogtreecommitdiffstats
path: root/eval
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2021-03-24 14:56:45 +0000
committerHåvard Pettersen <havardpe@oath.com>2021-03-24 15:01:34 +0000
commit83605debe0a6b3a53b339f24992c9a54511d2a28 (patch)
treedcd73fa28405aba498d48cd01d15e5da1a903570 /eval
parent08f5c940cd3160b07ea48ec1e814c7641597e078 (diff)
handle value decoding failures more gracefully
Diffstat (limited to 'eval')
-rw-r--r--eval/src/tests/eval/value_codec/value_codec_test.cpp12
-rw-r--r--eval/src/vespa/eval/eval/value_codec.cpp22
-rw-r--r--eval/src/vespa/eval/eval/value_codec.h5
3 files changed, 26 insertions, 13 deletions
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<Value> 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 <vespa/vespalib/stllike/string.h>
+#include <vespa/vespalib/util/exception.h>
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<Value> decode_value(nbostream &input, const ValueBuilderFactory &factory);