iceberg-cpp
Loading...
Searching...
No Matches
error_collector.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <string>
26#include <vector>
27
28#include "iceberg/compat/compiler.h"
30#include "iceberg/result.h"
31
32// The builder macros name Iceberg symbols with their full namespace, so builders outside
33// namespace iceberg can use them.
34#define ICEBERG_BUILDER_RETURN_IF_ERROR(result) \
35 if (auto&& result_name = result; !result_name) [[unlikely]] { \
36 errors_.emplace_back(std::move(result_name.error())); \
37 return *this; \
38 }
39
40#define ICEBERG_BUILDER_ASSIGN_OR_RETURN_IMPL(result_name, lhs, rexpr) \
41 auto&& result_name = (rexpr); \
42 ICEBERG_BUILDER_RETURN_IF_ERROR(result_name) \
43 lhs = std::move(result_name.value());
44
45#define ICEBERG_BUILDER_ASSIGN_OR_RETURN(lhs, rexpr) \
46 ICEBERG_BUILDER_ASSIGN_OR_RETURN_IMPL( \
47 ICEBERG_ASSIGN_OR_RAISE_NAME(result_, __COUNTER__), lhs, rexpr)
48
49#define ICEBERG_BUILDER_ASSIGN_OR_RETURN_WITH_ERROR_IMPL(result_name, lhs, rexpr, ...) \
50 auto&& result_name = (rexpr); \
51 if (!result_name) [[unlikely]] { \
52 AddError(::iceberg::ErrorKind::kInvalidArgument, __VA_ARGS__); \
53 return *this; \
54 } \
55 lhs = std::move(result_name.value());
56
57#define ICEBERG_BUILDER_ASSIGN_OR_RETURN_WITH_ERROR(lhs, rexpr, ...) \
58 ICEBERG_BUILDER_ASSIGN_OR_RETURN_WITH_ERROR_IMPL( \
59 ICEBERG_ASSIGN_OR_RAISE_NAME(result_, __COUNTER__), lhs, rexpr, __VA_ARGS__)
60
61#define ICEBERG_BUILDER_CHECK(expr, ...) \
62 do { \
63 if (!(expr)) [[unlikely]] { \
64 AddError(::iceberg::ErrorKind::kInvalidArgument, __VA_ARGS__); \
65 return *this; \
66 } \
67 } while (false)
68
69namespace iceberg {
70
99class ICEBERG_EXPORT ErrorCollector {
100 public:
101 ErrorCollector() = default;
102 virtual ~ErrorCollector() = default;
103
104 ErrorCollector(ErrorCollector&&) = default;
105 ErrorCollector& operator=(ErrorCollector&&) = default;
106
107 ErrorCollector(const ErrorCollector&) = default;
108 ErrorCollector& operator=(const ErrorCollector&) = default;
109
117#if ICEBERG_CXX20_COMPAT
118 template <typename... Args>
119 ErrorCollector& AddError(ErrorKind kind, const std::format_string<Args...> fmt,
120 Args&&... args) {
121 RecordError({kind, std::format(fmt, std::forward<Args>(args)...)});
122 return *this;
123 }
124#else
125 template <typename... Args>
126 auto& AddError(this auto& self, ErrorKind kind, const std::format_string<Args...> fmt,
127 Args&&... args) {
128 static_cast<ErrorCollector&>(self).RecordError(
129 {kind, std::format(fmt, std::forward<Args>(args)...)});
130 return self;
131 }
132#endif
133
142#if ICEBERG_CXX20_COMPAT
143 ErrorCollector& AddError(Error err) {
144 RecordError(std::move(err));
145 return *this;
146 }
147#else
148 auto& AddError(this auto& self, Error err) {
149 static_cast<ErrorCollector&>(self).RecordError(std::move(err));
150 return self;
151 }
152#endif
153
165#if ICEBERG_CXX20_COMPAT
167 RecordError(std::move(err.error()));
168 return *this;
169 }
170#else
171 auto& AddError(this auto& self, ::iceberg::unexpected<Error> err) {
172 static_cast<ErrorCollector&>(self).RecordError(std::move(err.error()));
173 return self;
174 }
175 auto& AddError(this auto& self, std::unexpected<Error> err) {
176 static_cast<ErrorCollector&>(self).RecordError(std::move(err.error()));
177 return self;
178 }
179#endif
180
184 [[nodiscard]] bool has_errors() const { return !errors_.empty(); }
185
189 [[nodiscard]] size_t error_count() const { return errors_.size(); }
190
200 [[nodiscard]] Status CheckErrors() const {
201 if (!errors_.empty()) {
202 std::string error_msg = "Validation failed due to the following errors:\n";
203 bool all_retryable = true;
204 for (const auto& [kind, message] : errors_) {
205 all_retryable &= kind == ErrorKind::kRetryableValidationFailed;
206 error_msg += " - " + message + "\n";
207 }
208 if (all_retryable) {
209 return RetryableValidationFailed("{}", error_msg);
210 }
211 return ValidationFailed("{}", error_msg);
212 }
213 return {};
214 }
215
220 void ClearErrors() { errors_.clear(); }
221
223 [[nodiscard]] const std::vector<Error>& errors() const { return errors_; }
224
225 private:
226 void RecordError(Error err) { errors_.push_back(std::move(err)); }
227
228 protected:
229 std::vector<Error> errors_;
230};
231
232} // namespace iceberg
Base class for collecting errors in the builder pattern.
Definition error_collector.h:99
const std::vector< Error > & errors() const
Get read-only access to all collected errors.
Definition error_collector.h:223
Status CheckErrors() const
Check for accumulated errors and return them if any exist.
Definition error_collector.h:200
void ClearErrors()
Clear all accumulated errors.
Definition error_collector.h:220
auto & AddError(this auto &self, ::iceberg::unexpected< Error > err)
Add an unexpected result's error.
Definition error_collector.h:171
auto & AddError(this auto &self, ErrorKind kind, const std::format_string< Args... > fmt, Args &&... args)
Add a specific error.
Definition error_collector.h:126
auto & AddError(this auto &self, Error err)
Add an existing error object.
Definition error_collector.h:148
bool has_errors() const
Check if any errors have been collected.
Definition error_collector.h:184
size_t error_count() const
Get the number of errors collected.
Definition error_collector.h:189
Definition expected.h:1199
Definition expected.h:246
Define symbol visibility macros for core Iceberg APIs.
Core Apache Iceberg C++ APIs.
Definition arrow_io_util.h:34
ErrorKind
Error types for iceberg.
Definition result.h:36
Define Result, Status, and error helpers.
Error with a kind and a message.
Definition result.h:76