Skip to content

Commit accde9e

Browse files
jckingcopybara-github
authored andcommitted
Return somewhat expected errors as cel::ErrorValue instead of absl::Status
PiperOrigin-RevId: 688594318
1 parent 1884d2c commit accde9e

16 files changed

Lines changed: 102 additions & 51 deletions

common/values/error_value.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <cstddef>
1516
#include <string>
1617
#include <utility>
1718

@@ -79,6 +80,16 @@ ErrorValue TypeConversionError(const Type& from, const Type& to) {
7980
return TypeConversionError(from.DebugString(), to.DebugString());
8081
}
8182

83+
ErrorValue IndexOutOfBoundsError(size_t index) {
84+
return ErrorValue(
85+
absl::InvalidArgumentError(absl::StrCat("index out of bounds: ", index)));
86+
}
87+
88+
ErrorValue IndexOutOfBoundsError(ptrdiff_t index) {
89+
return ErrorValue(
90+
absl::InvalidArgumentError(absl::StrCat("index out of bounds: ", index)));
91+
}
92+
8293
bool IsNoSuchField(const ErrorValue& value) {
8394
return absl::IsNotFound(value.NativeValue()) &&
8495
absl::StartsWith(value.NativeValue().message(), "no_such_field");

common/values/error_value.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#ifndef THIRD_PARTY_CEL_CPP_COMMON_VALUES_ERROR_VALUE_H_
1919
#define THIRD_PARTY_CEL_CPP_COMMON_VALUES_ERROR_VALUE_H_
2020

21+
#include <cstddef>
2122
#include <ostream>
2223
#include <string>
24+
#include <type_traits>
2325
#include <utility>
2426

2527
#include "absl/base/nullability.h"
@@ -123,6 +125,29 @@ ErrorValue TypeConversionError(absl::string_view from, absl::string_view to);
123125

124126
ErrorValue TypeConversionError(const Type& from, const Type& to);
125127

128+
ErrorValue IndexOutOfBoundsError(size_t index);
129+
130+
ErrorValue IndexOutOfBoundsError(ptrdiff_t index);
131+
132+
// Catch other integrals and forward them to the above ones. This is needed to
133+
// avoid ambiguous overload issues for smaller integral types like `int`.
134+
template <typename T>
135+
std::enable_if_t<std::conjunction_v<std::is_integral<T>, std::is_unsigned<T>,
136+
std::negation<std::is_same<T, size_t>>>,
137+
ErrorValue>
138+
IndexOutOfBoundsError(T index) {
139+
static_assert(sizeof(T) <= sizeof(size_t));
140+
return IndexOutOfBoundsError(static_cast<size_t>(index));
141+
}
142+
template <typename T>
143+
std::enable_if_t<std::conjunction_v<std::is_integral<T>, std::is_signed<T>,
144+
std::negation<std::is_same<T, ptrdiff_t>>>,
145+
ErrorValue>
146+
IndexOutOfBoundsError(T index) {
147+
static_assert(sizeof(T) <= sizeof(ptrdiff_t));
148+
return IndexOutOfBoundsError(static_cast<ptrdiff_t>(index));
149+
}
150+
126151
inline std::ostream& operator<<(std::ostream& out, const ErrorValue& value) {
127152
return out << value.DebugString();
128153
}

common/values/list_value_test.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "common/json.h"
2525
#include "common/memory.h"
2626
#include "common/type.h"
27-
#include "common/type_factory.h"
2827
#include "common/value.h"
2928
#include "common/value_testing.h"
3029
#include "internal/status_macros.h"
@@ -35,6 +34,7 @@ namespace {
3534

3635
using ::absl_testing::IsOkAndHolds;
3736
using ::absl_testing::StatusIs;
37+
using ::cel::test::ErrorValueIs;
3838
using ::testing::ElementsAreArray;
3939
using ::testing::TestParamInfo;
4040

@@ -107,8 +107,9 @@ TEST_P(ListValueTest, Get) {
107107
ASSERT_OK_AND_ASSIGN(element, value.Get(value_manager(), 2));
108108
ASSERT_TRUE(InstanceOf<IntValue>(element));
109109
ASSERT_EQ(Cast<IntValue>(element).NativeValue(), 2);
110-
EXPECT_THAT(value.Get(value_manager(), 3),
111-
StatusIs(absl::StatusCode::kInvalidArgument));
110+
EXPECT_THAT(
111+
value.Get(value_manager(), 3),
112+
IsOkAndHolds(ErrorValueIs(StatusIs(absl::StatusCode::kInvalidArgument))));
112113
}
113114

114115
TEST_P(ListValueTest, ForEach) {

common/values/map_value_test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ namespace {
3737
using ::absl_testing::IsOk;
3838
using ::absl_testing::IsOkAndHolds;
3939
using ::absl_testing::StatusIs;
40+
using ::cel::test::ErrorValueIs;
4041
using ::testing::IsEmpty;
4142
using ::testing::Not;
4243
using ::testing::TestParamInfo;
@@ -150,8 +151,9 @@ TEST_P(MapValueTest, Get) {
150151
ASSERT_OK_AND_ASSIGN(value, map_value.Get(value_manager(), IntValue(2)));
151152
ASSERT_TRUE(InstanceOf<DoubleValue>(value));
152153
ASSERT_EQ(Cast<DoubleValue>(value).NativeValue(), 5.0);
153-
EXPECT_THAT(map_value.Get(value_manager(), IntValue(3)),
154-
StatusIs(absl::StatusCode::kNotFound));
154+
EXPECT_THAT(
155+
map_value.Get(value_manager(), IntValue(3)),
156+
IsOkAndHolds(ErrorValueIs(StatusIs(absl::StatusCode::kNotFound))));
155157
}
156158

157159
TEST_P(MapValueTest, Find) {

common/values/mutable_list_value_test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace {
3838
using ::absl_testing::IsOk;
3939
using ::absl_testing::IsOkAndHolds;
4040
using ::absl_testing::StatusIs;
41+
using ::cel::test::ErrorValueIs;
4142
using ::cel::test::StringValueIs;
4243
using ::testing::IsEmpty;
4344
using ::testing::Pair;
@@ -156,8 +157,9 @@ TEST_P(MutableListValueTest, Get) {
156157
auto mutable_list_value = NewMutableListValue(allocator());
157158
mutable_list_value->Reserve(1);
158159
Value value;
159-
EXPECT_THAT(mutable_list_value->Get(value_manager(), 0, value),
160-
StatusIs(absl::StatusCode::kInvalidArgument));
160+
EXPECT_THAT(mutable_list_value->Get(value_manager(), 0, value), IsOk());
161+
EXPECT_THAT(value,
162+
ErrorValueIs(StatusIs(absl::StatusCode::kInvalidArgument)));
161163
EXPECT_THAT(mutable_list_value->Append(StringValue("foo")), IsOk());
162164
EXPECT_THAT(mutable_list_value->Get(value_manager(), 0, value), IsOk());
163165
EXPECT_THAT(value, StringValueIs("foo"));

common/values/parsed_json_list_value.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,15 @@ size_t ParsedJsonListValue::Size() const {
149149
absl::Status ParsedJsonListValue::Get(ValueManager& value_manager, size_t index,
150150
Value& result) const {
151151
if (value_ == nullptr) {
152-
return absl::InvalidArgumentError("index out of bounds");
152+
result = IndexOutOfBoundsError(index);
153+
return absl::OkStatus();
153154
}
154155
const auto reflection =
155156
well_known_types::GetListValueReflectionOrDie(value_->GetDescriptor());
156157
if (ABSL_PREDICT_FALSE(index >=
157158
static_cast<size_t>(reflection.ValuesSize(*value_)))) {
158-
return absl::InvalidArgumentError("index out of bounds");
159+
result = IndexOutOfBoundsError(index);
160+
return absl::OkStatus();
159161
}
160162
result = common_internal::ParsedJsonValue(
161163
value_manager.GetMemoryManager().arena(),

common/values/parsed_json_list_value_test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ using ::absl_testing::StatusIs;
5050
using ::cel::internal::GetTestingDescriptorPool;
5151
using ::cel::internal::GetTestingMessageFactory;
5252
using ::cel::test::BoolValueIs;
53+
using ::cel::test::ErrorValueIs;
5354
using ::cel::test::IsNullValue;
5455
using ::testing::ElementsAre;
5556
using ::testing::IsEmpty;
@@ -193,8 +194,9 @@ TEST_P(ParsedJsonListValueTest, Get_Dynamic) {
193194
EXPECT_THAT(valid_value.Get(value_manager(), 0), IsOkAndHolds(IsNullValue()));
194195
EXPECT_THAT(valid_value.Get(value_manager(), 1),
195196
IsOkAndHolds(BoolValueIs(true)));
196-
EXPECT_THAT(valid_value.Get(value_manager(), 2),
197-
StatusIs(absl::StatusCode::kInvalidArgument));
197+
EXPECT_THAT(
198+
valid_value.Get(value_manager(), 2),
199+
IsOkAndHolds(ErrorValueIs(StatusIs(absl::StatusCode::kInvalidArgument))));
198200
}
199201

200202
TEST_P(ParsedJsonListValueTest, ForEach_Dynamic) {

common/values/parsed_json_map_value.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "absl/status/status.h"
2727
#include "absl/status/statusor.h"
2828
#include "absl/strings/cord.h"
29-
#include "absl/strings/str_cat.h"
3029
#include "absl/strings/string_view.h"
3130
#include "common/allocator.h"
3231
#include "common/json.h"
@@ -153,8 +152,7 @@ absl::Status ParsedJsonMapValue::Get(ValueManager& value_manager,
153152
const Value& key, Value& result) const {
154153
CEL_ASSIGN_OR_RETURN(bool ok, Find(value_manager, key, result));
155154
if (ABSL_PREDICT_FALSE(!ok) && !(result.IsError() || result.IsUnknown())) {
156-
return absl::NotFoundError(
157-
absl::StrCat("Key not found in map : ", key.DebugString()));
155+
result = NoSuchKeyError(key.DebugString());
158156
}
159157
return absl::OkStatus();
160158
}

common/values/parsed_json_map_value_test.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ using ::absl_testing::StatusIs;
5050
using ::cel::internal::GetTestingDescriptorPool;
5151
using ::cel::internal::GetTestingMessageFactory;
5252
using ::cel::test::BoolValueIs;
53+
using ::cel::test::ErrorValueIs;
5354
using ::cel::test::IsNullValue;
5455
using ::cel::test::StringValueIs;
5556
using ::testing::AnyOf;
@@ -202,14 +203,16 @@ TEST_P(ParsedJsonMapValueTest, Get_Dynamic) {
202203
key: "bar"
203204
value: { bool_value: true }
204205
})pb"));
205-
EXPECT_THAT(valid_value.Get(value_manager(), BoolValue()),
206-
StatusIs(absl::StatusCode::kNotFound));
206+
EXPECT_THAT(
207+
valid_value.Get(value_manager(), BoolValue()),
208+
IsOkAndHolds(ErrorValueIs(StatusIs(absl::StatusCode::kNotFound))));
207209
EXPECT_THAT(valid_value.Get(value_manager(), StringValue("foo")),
208210
IsOkAndHolds(IsNullValue()));
209211
EXPECT_THAT(valid_value.Get(value_manager(), StringValue("bar")),
210212
IsOkAndHolds(BoolValueIs(true)));
211-
EXPECT_THAT(valid_value.Get(value_manager(), StringValue("baz")),
212-
StatusIs(absl::StatusCode::kNotFound));
213+
EXPECT_THAT(
214+
valid_value.Get(value_manager(), StringValue("baz")),
215+
IsOkAndHolds(ErrorValueIs(StatusIs(absl::StatusCode::kNotFound))));
213216
}
214217

215218
TEST_P(ParsedJsonMapValueTest, Find_Dynamic) {

common/values/parsed_list_value.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ absl::Status ParsedListValueInterface::SerializeTo(
134134
absl::Status ParsedListValueInterface::Get(ValueManager& value_manager,
135135
size_t index, Value& result) const {
136136
if (ABSL_PREDICT_FALSE(index >= Size())) {
137-
return absl::InvalidArgumentError("index out of bounds");
137+
result = IndexOutOfBoundsError(index);
138+
return absl::OkStatus();
138139
}
139140
return GetImpl(value_manager, index, result);
140141
}

0 commit comments

Comments
 (0)