diff --git a/doc/qbk/03_7_tutorial_error_handling.qbk b/doc/qbk/03_7_tutorial_error_handling.qbk index 807f5009..cb382a2e 100644 --- a/doc/qbk/03_7_tutorial_error_handling.qbk +++ b/doc/qbk/03_7_tutorial_error_handling.qbk @@ -46,12 +46,12 @@ Why are we not seeing the error code? When an awaitable in Asio is co_await'ed, the first handler argument is inspected. If it's an `error_code` that indicates a failure, an exception is thrown. -The `error_code` is removed and not returned from the co_await expression, -thus seeing only `mysql::pooled_connection`. +The `error_code` is removed from the argument list, +leaving a `mysql::pooled_connection` only. [asioreflink as_tuple as_tuple] is a completion token that modifies the handler signature, packing all arguments into a `std::tuple`. -It's used similarly to the `asio::cancel_after` token we have learnt in the previous tutorial: +It's used similarly to the `asio::cancel_after` token that we used in the previous tutorial: [tutorial_error_handling_get_connection_as_tuple] @@ -67,9 +67,7 @@ In practice, it's usually better to use structured bindings: [heading Using asio::as_tuple for database code] -An error when talking to the database implies only sending a special value to the client. -This means that the function encapsulating database logic can maintain its original signature. -Applying [asioreflink as_tuple as_tuple] yields: +If we apply [asioreflink as_tuple as_tuple] to our database logic, we have: [tutorial_error_handling_db_nodiag] @@ -89,7 +87,7 @@ When using error codes, we need to handle diagnostics manually. All functions in Boost.MySQL are overloaded to accept a [reflink diagnostics] output parameter. It will be populated with extra information in case of error. -Let's update our code to use it: +Let's update our code to use diagnostics: [tutorial_error_handling_db] diff --git a/example/1_tutorial/7_error_handling.cpp b/example/1_tutorial/7_error_handling.cpp index 1f36f78d..25334ab1 100644 --- a/example/1_tutorial/7_error_handling.cpp +++ b/example/1_tutorial/7_error_handling.cpp @@ -96,6 +96,7 @@ struct employee //[tutorial_error_handling_db asio::awaitable get_employee_details(mysql::connection_pool& pool, std::int64_t employee_id) { + // Will be populated with error information in case of error mysql::diagnostics diag; // Get a connection from the pool. @@ -103,6 +104,7 @@ asio::awaitable get_employee_details(mysql::connection_pool& pool, // pooled_connection grants us exclusive access to the connection until // the object is destroyed //[tutorial_error_handling_structured_bindings + // ec is an error_code, conn is the mysql::pooled_connection auto [ec, conn] = co_await pool.async_get_connection(diag, asio::as_tuple); //] if (ec) diff --git a/test/integration/test/snippets/tutorials.cpp b/test/integration/test/snippets/tutorials.cpp index 88ab9586..253f3ffa 100644 --- a/test/integration/test/snippets/tutorials.cpp +++ b/test/integration/test/snippets/tutorials.cpp @@ -240,7 +240,7 @@ asio::awaitable tutorial_connection_pool_unused( void log_error(const char*, boost::system::error_code) {} // Version without diagnostics -// [tutorial_error_handling_db_nodiag +//[tutorial_error_handling_db_nodiag asio::awaitable get_employee_details(mysql::connection_pool& pool, std::int64_t employee_id) { // Get a connection from the pool. @@ -248,6 +248,8 @@ asio::awaitable get_employee_details(mysql::connection_pool& pool, auto [ec, conn] = co_await pool.async_get_connection(asio::as_tuple); if (ec) { + // A connection couldn't be obtained. + // This may be because the session timed out. log_error("Error in async_get_connection", ec); co_return "ERROR"; }