1#include "duckdb/main/error_manager.hpp"
2#include "duckdb/main/config.hpp"
3#include "utf8proc_wrapper.hpp"
4
5namespace duckdb {
6
7struct DefaultError {
8 ErrorType type;
9 const char *error;
10};
11
12static DefaultError internal_errors[] = {
13 {.type: ErrorType::UNSIGNED_EXTENSION,
14 .error: "Extension \"%s\" could not be loaded because its signature is either missing or invalid and unsigned extensions "
15 "are disabled by configuration (allow_unsigned_extensions)"},
16 {.type: ErrorType::INVALIDATED_TRANSACTION, .error: "Current transaction is aborted (please ROLLBACK)"},
17 {.type: ErrorType::INVALIDATED_DATABASE, .error: "Failed: database has been invalidated because of a previous fatal error. The "
18 "database must be restarted prior to being used again.\nOriginal error: \"%s\""},
19 {.type: ErrorType::INVALID, .error: nullptr}};
20
21string ErrorManager::FormatExceptionRecursive(ErrorType error_type, vector<ExceptionFormatValue> &values) {
22 if (error_type >= ErrorType::ERROR_COUNT) {
23 throw InternalException("Invalid error type passed to ErrorManager::FormatError");
24 }
25 auto entry = custom_errors.find(x: error_type);
26 string error;
27 if (entry == custom_errors.end()) {
28 // error was not overwritten
29 error = internal_errors[int(error_type)].error;
30 } else {
31 // error was overwritten
32 error = entry->second;
33 }
34 return ExceptionFormatValue::Format(msg: error, values);
35}
36
37string ErrorManager::InvalidUnicodeError(const string &input, const string &context) {
38 UnicodeInvalidReason reason;
39 size_t pos;
40 auto unicode = Utf8Proc::Analyze(s: const_char_ptr_cast(src: input.c_str()), len: input.size(), invalid_reason: &reason, invalid_pos: &pos);
41 if (unicode != UnicodeType::INVALID) {
42 return "Invalid unicode error thrown but no invalid unicode detected in " + context;
43 }
44 string base_message;
45 switch (reason) {
46 case UnicodeInvalidReason::BYTE_MISMATCH:
47 base_message = "Invalid unicode (byte sequence mismatch)";
48 break;
49 case UnicodeInvalidReason::INVALID_UNICODE:
50 base_message = "Invalid unicode";
51 break;
52 default:
53 break;
54 }
55 return base_message + " detected in " + context;
56}
57
58void ErrorManager::AddCustomError(ErrorType type, string new_error) {
59 custom_errors.insert(x: make_pair(x&: type, y: std::move(new_error)));
60}
61
62ErrorManager &ErrorManager::Get(ClientContext &context) {
63 return *DBConfig::GetConfig(context).error_manager;
64}
65
66ErrorManager &ErrorManager::Get(DatabaseInstance &context) {
67 return *DBConfig::GetConfig(db&: context).error_manager;
68}
69
70} // namespace duckdb
71