/* * Copyright (C) 2024-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #pragma once #include #include #include #include #include #include #include "utils/http_client_error_processing.hh" namespace aws { enum class aws_error_type : uint8_t { INCOMPLETE_SIGNATURE = 0, INTERNAL_FAILURE = 1, INVALID_ACTION = 2, INVALID_CLIENT_TOKEN_ID = 3, INVALID_PARAMETER_COMBINATION = 4, INVALID_QUERY_PARAMETER = 5, INVALID_PARAMETER_VALUE = 6, MISSING_ACTION = 7, MISSING_AUTHENTICATION_TOKEN = 8, MISSING_PARAMETER = 9, OPT_IN_REQUIRED = 10, REQUEST_EXPIRED = 11, SERVICE_UNAVAILABLE = 12, THROTTLING = 13, VALIDATION = 14, ACCESS_DENIED = 15, RESOURCE_NOT_FOUND = 16, UNRECOGNIZED_CLIENT = 17, MALFORMED_QUERY_STRING = 18, SLOW_DOWN = 19, REQUEST_TIME_TOO_SKEWED = 20, INVALID_SIGNATURE = 21, SIGNATURE_DOES_NOT_MATCH = 22, INVALID_ACCESS_KEY_ID = 23, REQUEST_TIMEOUT = 24, NOT_INITIALIZED = 25, MEMORY_ALLOCATION = 26, NETWORK_CONNECTION = 99, UNKNOWN = 100, CLIENT_SIGNING_FAILURE = 101, USER_CANCELLED = 102, ENDPOINT_RESOLUTION_FAILURE = 103, // HTTP errors without additional information in the response body HTTP_UNAUTHORIZED = 115, HTTP_FORBIDDEN = 116, HTTP_NOT_FOUND = 117, HTTP_TOO_MANY_REQUESTS = 118, HTTP_INTERNAL_SERVER_ERROR = 119, HTTP_BANDWIDTH_LIMIT_EXCEEDED = 120, HTTP_SERVICE_UNAVAILABLE = 121, HTTP_REQUEST_TIMEOUT = 122, HTTP_PAGE_EXPIRED = 123, HTTP_LOGIN_TIMEOUT = 124, HTTP_GATEWAY_TIMEOUT = 125, HTTP_NETWORK_CONNECT_TIMEOUT = 126, HTTP_NETWORK_READ_TIMEOUT = 127, SERVICE_EXTENSION_START_RANGE = 128, // S3 specific BUCKET_ALREADY_EXISTS = 129, BUCKET_ALREADY_OWNED_BY_YOU = 130, INVALID_OBJECT_STATE = 131, NO_SUCH_BUCKET = 132, NO_SUCH_KEY = 133, NO_SUCH_UPLOAD = 134, OBJECT_ALREADY_IN_ACTIVE_TIER = 135, OBJECT_NOT_IN_ACTIVE_TIER = 136, // STS specific EXPIRED_TOKEN = 137, INVALID_AUTHORIZATION_MESSAGE = 138, INVALID_IDENTITY_TOKEN = 139, I_D_P_COMMUNICATION_ERROR = 140, I_D_P_REJECTED_CLAIM = 141, MALFORMED_POLICY_DOCUMENT = 142, PACKED_POLICY_TOO_LARGE = 143, REGION_DISABLED = 144, // No error set OK = 255 }; class aws_error; using aws_errors = std::unordered_map; class aws_error { aws_error_type _type{aws_error_type::OK}; std::string _message; utils::http::retryable _is_retryable{utils::http::retryable::no}; public: aws_error() = default; aws_error(aws_error_type error_type, utils::http::retryable is_retryable); aws_error(aws_error_type error_type, std::string&& error_message, utils::http::retryable is_retryable); [[nodiscard]] const std::string& get_error_message() const { return _message; } [[nodiscard]] aws_error_type get_error_type() const { return _type; } [[nodiscard]] utils::http::retryable is_retryable() const { return _is_retryable; } static std::optional parse(seastar::sstring&& body); static aws_error from_http_code(seastar::http::reply::status_type http_code); static aws_error from_system_error(const std::system_error& system_error); static aws_error from_exception_ptr(std::exception_ptr exception); static const aws_errors& get_errors(); }; class aws_exception : public std::exception { aws_error _error; public: explicit aws_exception(const aws_error& error) noexcept : _error(error) {} explicit aws_exception(aws_error&& error) noexcept : _error(std::move(error)) {} const char* what() const noexcept override { return _error.get_error_message().c_str(); } const aws_error& error() const noexcept { return _error; } }; } // namespace aws template <> struct fmt::formatter : fmt::formatter { auto format(const aws::aws_error_type& error_type, fmt::format_context& ctx) const { return fmt::format_to(ctx.out(), "{}", static_cast(error_type)); } };