[/ Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] [section:error_handling Error handling and available overloads] This section describes the different error handling strategies you may use with this library, as well as the different overloads available for each function involving network transfers. This library uses Boost.System error codes and exceptions, like Asio and Beast. Some server-reported errors may include additional diagnostics information. For example, if you issue a query and one of the referenced fields does not exist, the server will return an error message indicating which was the offending field. This library makes these diagnostics available through the following classes and functions: [variablelist [ [[reflink diagnostics]] [ An object containing this extra diagnostic information about an error. [refmem diagnostics server_message] contains the server-generated error string, if any. ] ] [ [[reflink error_with_diagnostics]] [ An exception that inherits from `boost::system::system_error` that contains a `diagnostics` object. ] ] [ [[reflink with_diagnostics]] [A completion token that embeds diagnostics in exceptions thrown by async functions.] ] [ [[reflink is_fatal_error]] [Checks whether an `error_code` is [link mysql.error_handling.fatal fatal] and thus requires re-establishing the connection.] ] ] Every piece of functionality involving network transfers is offered in four versions: * [*Synchronous with exceptions]. When they fail, they throw an [reflink error_with_diagnostics] exception. * [*Synchronous with [reflink error_code] and [reflink diagnostics]]. These functions output an `error_code` and a `diagnostics` object by lvalue reference to report failures. * [*Asynchronous, without `diagnostics`]. When they fail, they call the completion handler with a non-empty `error_code`. * [*Asynchronous, with `diagnostics`]. They have a `diagnostics&` parameter before the `CompletionToken`. When they fail, they set the `diagnostics` parameter to any server-provided diagnostic information, if available, and then call the completion handler with a non-empty `error_code`. [heading Types of errors] This library defines the following types of errors: [table [ [Type of error] [Values contained in...] [Error category] [Description] ] [ [Client errors] [[reflink client_errc] enum] [[reflink get_client_category]] [Failures detected by Boost.MySQL, like corrupt messages.] ] [ [Common server errors] [[reflink common_server_errc] enum] [[reflink get_common_server_category]] [ Errors reported by the server, common to both MySQL and MariaDB. No new codes will be added here, since the two DBs are currently developed independently. ] ] [ [MySQL-specific server errors] [Integer codes in [br][include_file boost/mysql/mysql_server_errc.hpp]] [[reflink get_mysql_server_category]] [ Errors reported by the server, specific to MySQL. New codes will be added in the future. ] ] [ [MariaDB-specific server errors] [Integer codes in [br][include_file boost/mysql/mariadb_server_errc.hpp]] [[reflink get_mariadb_server_category]] [ Errors reported by the server, specific to MariaDB. New codes will be added in the future. ] ] ] Note that new codes are added frequently, so server-specific codes are represented as integers, instead of enums. [heading:fatal Fatal vs. non-fatal errors] When an operation on a established connection (like a query execution) results in an error, two situations may happen: * The connection object is left in a well-known state. You can safely use the object to run further operations without problems. For instance, if a query fails with `common_server_errc::er_no_such_table` because you misspelled a table name, it is safe to run other queries after the failed one. Such errors are called [*non-fatal]. * The connection object is left un an unknown state. Further operations will fail with unpredictable results. You should close and re-establish the connection. These are [*fatal] errors, and include protocol and network errors. You can use [reflink is_fatal_error] to distinguish between fatal and non-fatal error codes. [heading Security notes on diagnostics] The error message given by [refmem diagnostics server_message] [*may contain user-provided input, and should be treated as untrusted]. For certain errors, the MySQL server will include the offending field names and values, which may contain arbitrary input. Please use with caution. This message may contain non-ASCII characters. It's encoded using the connection's character set. [heading:system_result Using boost::system::result] Some functions, like [refmem basic_format_context get], use [@boost:/libs/system/doc/html/system.html#ref_boostsystemresult_hpp `boost::system::result`] to communicate errors. `result` contains either a value (an instance of `T`), or an [reflink error_code], if the operation failed. `result` is similar to `std::expected`, but only requires C++11. Given a `result` object `r`, you can get its contained value calling `r.value()`. If `r` contained an error, a `boost::system::result` exception with the contained error code is thrown. `r.has_value()`, `r.has_error()` and `r.error()` can be used to inspect the object. [endsect]