Coverage Report

Created: 2026-10-09 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/values/error_value.cc
Line
Count
Source
1
// Copyright 2023 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <cstddef>
16
#include <string>
17
18
#include "absl/base/no_destructor.h"
19
#include "absl/base/nullability.h"
20
#include "absl/log/absl_check.h"
21
#include "absl/status/status.h"
22
#include "absl/strings/match.h"
23
#include "absl/strings/str_cat.h"
24
#include "absl/strings/string_view.h"
25
#include "common/type.h"
26
#include "common/value.h"
27
#include "google/protobuf/arena.h"
28
#include "google/protobuf/descriptor.h"
29
#include "google/protobuf/io/zero_copy_stream.h"
30
#include "google/protobuf/message.h"
31
32
namespace cel {
33
34
namespace {
35
36
0
std::string ErrorDebugString(const absl::Status& value) {
37
0
  ABSL_DCHECK(!value.ok()) << "use of moved-from ErrorValue";
38
0
  return value.ToString(absl::StatusToStringMode::kWithEverything);
39
0
}
40
41
0
const absl::Status& DefaultErrorValue() {
42
0
  static const absl::NoDestructor<absl::Status> value(
43
0
      absl::UnknownError("unknown error"));
44
0
  return *value;
45
0
}
46
47
407k
absl::Status MakeNoSuchFieldError(absl::string_view field) {
48
407k
  return absl::NotFoundError(
49
407k
      absl::StrCat("no_such_field", field.empty() ? "" : " : ", field));
50
407k
}
51
52
1.49k
absl::Status MakeNoSuchKeyError(absl::string_view key) {
53
1.49k
  return absl::NotFoundError(absl::StrCat("Key not found in map : ", key));
54
1.49k
}
55
56
0
absl::Status MakeNoSuchTypeError(absl::string_view type) {
57
0
  return absl::NotFoundError(absl::StrCat("type not found: ", type));
58
0
}
59
60
absl::Status MakeTypeConversionError(absl::string_view from,
61
29.5k
                                     absl::string_view to) {
62
29.5k
  return absl::InvalidArgumentError(
63
29.5k
      absl::StrCat("type conversion error from '", from, "' to '", to, "'"));
64
29.5k
}
65
66
0
absl::Status MakeIndexOutOfBoundsError(size_t index) {
67
0
  return absl::InvalidArgumentError(
68
0
      absl::StrCat("index out of bounds: ", index));
69
0
}
70
71
0
absl::Status MakeIndexOutOfBoundsError(ptrdiff_t index) {
72
0
  return absl::InvalidArgumentError(
73
0
      absl::StrCat("index out of bounds: ", index));
74
0
}
75
76
}  // namespace
77
78
namespace common_internal {
79
80
8
absl::Status MakeTypeConversionError(const Type& from, const Type& to) {
81
8
  return cel::MakeTypeConversionError(from.DebugString(), to.DebugString());
82
8
}
83
84
absl::Status MakeTypeConversionError(absl::string_view from,
85
12
                                     absl::string_view to) {
86
12
  return cel::MakeTypeConversionError(from, to);
87
12
}
88
89
0
absl::Status MakeNoSuchFieldError(absl::string_view field) {
90
0
  return cel::MakeNoSuchFieldError(field);
91
0
}
92
93
0
absl::Status MakeNoSuchKeyError(absl::string_view key) {
94
0
  return cel::MakeNoSuchKeyError(key);
95
0
}
96
97
0
absl::Status MakeIndexOutOfBoundsError(size_t index) {
98
0
  return cel::MakeIndexOutOfBoundsError(index);
99
0
}
100
101
0
absl::Status MakeIndexOutOfBoundsError(ptrdiff_t index) {
102
0
  return cel::MakeIndexOutOfBoundsError(index);
103
0
}
104
105
}  // namespace common_internal
106
107
0
ErrorValue::ErrorValue() : ErrorValue(nullptr, &DefaultErrorValue()) {}
108
109
ErrorValue NoSuchFieldError(absl::string_view field,
110
407k
                            google::protobuf::Arena* absl_nonnull arena) {
111
407k
  return ErrorValue::From(MakeNoSuchFieldError(field), arena);
112
407k
}
113
114
ErrorValue NoSuchKeyError(absl::string_view key,
115
1.49k
                          google::protobuf::Arena* absl_nonnull arena) {
116
1.49k
  return ErrorValue::From(MakeNoSuchKeyError(key), arena);
117
1.49k
}
118
119
ErrorValue NoSuchTypeError(absl::string_view type,
120
0
                           google::protobuf::Arena* absl_nonnull arena) {
121
0
  return ErrorValue::From(MakeNoSuchTypeError(type), arena);
122
0
}
123
124
37
ErrorValue DuplicateKeyError() {
125
37
  static const absl::NoDestructor<absl::Status> error(
126
37
      absl::AlreadyExistsError("duplicate key in map"));
127
37
  return ErrorValue(nullptr, &*error);
128
37
}
129
130
ErrorValue TypeConversionError(absl::string_view from, absl::string_view to,
131
29.5k
                               google::protobuf::Arena* absl_nonnull arena) {
132
29.5k
  return ErrorValue::From(MakeTypeConversionError(from, to), arena);
133
29.5k
}
134
135
ErrorValue TypeConversionError(const Type& from, const Type& to,
136
0
                               google::protobuf::Arena* absl_nonnull arena) {
137
0
  return TypeConversionError(from.DebugString(), to.DebugString(), arena);
138
0
}
139
140
ErrorValue IndexOutOfBoundsError(size_t index,
141
0
                                 google::protobuf::Arena* absl_nonnull arena) {
142
0
  return ErrorValue::From(MakeIndexOutOfBoundsError(index), arena);
143
0
}
144
145
ErrorValue IndexOutOfBoundsError(ptrdiff_t index,
146
0
                                 google::protobuf::Arena* absl_nonnull arena) {
147
0
  return ErrorValue::From(MakeIndexOutOfBoundsError(index), arena);
148
0
}
149
150
0
bool IsNoSuchField(const ErrorValue& value) {
151
0
  return absl::IsNotFound(value.NativeValue()) &&
152
0
         absl::StartsWith(value.NativeValue().message(), "no_such_field");
153
0
}
154
155
0
bool IsNoSuchKey(const ErrorValue& value) {
156
0
  return absl::IsNotFound(value.NativeValue()) &&
157
0
         absl::StartsWith(value.NativeValue().message(),
158
0
                          "Key not found in map");
159
0
}
160
161
0
std::string ErrorValue::DebugString() const {
162
0
  return ErrorDebugString(NativeValue());
163
0
}
164
165
absl::Status ErrorValue::SerializeTo(
166
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
167
    google::protobuf::MessageFactory* absl_nonnull message_factory,
168
0
    google::protobuf::io::ZeroCopyOutputStream* absl_nonnull output) const {
169
0
  ABSL_DCHECK(descriptor_pool != nullptr);
170
0
  ABSL_DCHECK(message_factory != nullptr);
171
0
  ABSL_DCHECK(output != nullptr);
172
0
  ABSL_DCHECK(*this);
173
174
0
  return absl::FailedPreconditionError(
175
0
      absl::StrCat(GetTypeName(), " is unserializable"));
176
0
}
177
178
absl::Status ErrorValue::ConvertToJson(
179
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
180
    google::protobuf::MessageFactory* absl_nonnull message_factory,
181
0
    google::protobuf::Message* absl_nonnull json) const {
182
0
  ABSL_DCHECK(descriptor_pool != nullptr);
183
0
  ABSL_DCHECK(message_factory != nullptr);
184
0
  ABSL_DCHECK(json != nullptr);
185
0
  ABSL_DCHECK_EQ(json->GetDescriptor()->well_known_type(),
186
0
                 google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE);
187
0
  ABSL_DCHECK(*this);
188
189
0
  return absl::FailedPreconditionError(
190
0
      absl::StrCat(GetTypeName(), " is not convertable to JSON"));
191
0
}
192
193
absl::Status ErrorValue::Equal(
194
    const Value& other,
195
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
196
    google::protobuf::MessageFactory* absl_nonnull message_factory,
197
0
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
198
0
  ABSL_DCHECK(descriptor_pool != nullptr);
199
0
  ABSL_DCHECK(message_factory != nullptr);
200
0
  ABSL_DCHECK(arena != nullptr);
201
0
  ABSL_DCHECK(result != nullptr);
202
0
  ABSL_DCHECK(*this);
203
204
0
  *result = FalseValue();
205
0
  return absl::OkStatus();
206
0
}
207
208
0
ErrorValue ErrorValue::Clone(google::protobuf::Arena* absl_nonnull arena) const {
209
0
  ABSL_DCHECK(arena != nullptr);
210
0
  ABSL_DCHECK(*this);
211
212
0
  if (arena_ == nullptr || arena_ != arena) {
213
0
    return ErrorValue(arena,
214
0
                      google::protobuf::Arena::Create<absl::Status>(arena, ToStatus()));
215
0
  }
216
0
  return *this;
217
0
}
218
219
9.53k
absl::Status ErrorValue::ToStatus() const {
220
9.53k
  ABSL_DCHECK(*this);
221
9.53k
  return *status_ptr_;
222
9.53k
}
223
224
}  // namespace cel