• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 gRPC authors.
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 //     http://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 "src/core/util/validation_errors.h"
16 
17 #include <grpc/support/port_platform.h>
18 #include <inttypes.h>
19 
20 #include <utility>
21 
22 #include "absl/log/log.h"
23 #include "absl/status/status.h"
24 #include "absl/strings/str_cat.h"
25 #include "absl/strings/str_join.h"
26 #include "absl/strings/strip.h"
27 
28 namespace grpc_core {
29 
PushField(absl::string_view ext)30 void ValidationErrors::PushField(absl::string_view ext) {
31   // Skip leading '.' for top-level field names.
32   if (fields_.empty()) absl::ConsumePrefix(&ext, ".");
33   fields_.emplace_back(std::string(ext));
34 }
35 
PopField()36 void ValidationErrors::PopField() { fields_.pop_back(); }
37 
AddError(absl::string_view error)38 void ValidationErrors::AddError(absl::string_view error) {
39   auto key = absl::StrJoin(fields_, "");
40   if (field_errors_[key].size() >= max_error_count_) {
41     VLOG(2) << "Ignoring validation error: too many errors found ("
42             << max_error_count_ << ")";
43     return;
44   }
45   field_errors_[key].emplace_back(error);
46 }
47 
FieldHasErrors() const48 bool ValidationErrors::FieldHasErrors() const {
49   return field_errors_.find(absl::StrJoin(fields_, "")) != field_errors_.end();
50 }
51 
status(absl::StatusCode code,absl::string_view prefix) const52 absl::Status ValidationErrors::status(absl::StatusCode code,
53                                       absl::string_view prefix) const {
54   if (field_errors_.empty()) return absl::OkStatus();
55   return absl::Status(code, message(prefix));
56 }
57 
message(absl::string_view prefix) const58 std::string ValidationErrors::message(absl::string_view prefix) const {
59   if (field_errors_.empty()) return "";
60   std::vector<std::string> errors;
61   for (const auto& p : field_errors_) {
62     if (p.second.size() > 1) {
63       errors.emplace_back(absl::StrCat("field:", p.first, " errors:[",
64                                        absl::StrJoin(p.second, "; "), "]"));
65     } else {
66       errors.emplace_back(
67           absl::StrCat("field:", p.first, " error:", p.second[0]));
68     }
69   }
70   return absl::StrCat(prefix, ": [", absl::StrJoin(errors, "; "), "]");
71 }
72 
73 }  // namespace grpc_core
74