is_fatal_error.ipp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //
  2. // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MYSQL_IMPL_IS_FATAL_ERROR_IPP
  8. #define BOOST_MYSQL_IMPL_IS_FATAL_ERROR_IPP
  9. #pragma once
  10. #include <boost/mysql/client_errc.hpp>
  11. #include <boost/mysql/common_server_errc.hpp>
  12. #include <boost/mysql/error_categories.hpp>
  13. #include <boost/mysql/is_fatal_error.hpp>
  14. bool boost::mysql::is_fatal_error(error_code ec) noexcept
  15. {
  16. // If there is no failure, it's not fatal
  17. if (!ec)
  18. return false;
  19. // Retrieve the error category
  20. const auto& cat = ec.category();
  21. if (cat == get_common_server_category())
  22. {
  23. // Server errors may or may not be fatal. MySQL defines a ton of different errors.
  24. // After some research, these are the ones I'd recommend to consider fatal
  25. auto code = static_cast<common_server_errc>(ec.value());
  26. switch (code)
  27. {
  28. // Different flavors of communication errors. These usually indicate that the connection
  29. // has been left in an unspecified state, and the safest is to reconnect it.
  30. case common_server_errc::er_unknown_com_error:
  31. case common_server_errc::er_aborting_connection:
  32. case common_server_errc::er_net_packet_too_large:
  33. case common_server_errc::er_net_read_error_from_pipe:
  34. case common_server_errc::er_net_fcntl_error:
  35. case common_server_errc::er_net_packets_out_of_order:
  36. case common_server_errc::er_net_uncompress_error:
  37. case common_server_errc::er_net_read_error:
  38. case common_server_errc::er_net_read_interrupted:
  39. case common_server_errc::er_net_error_on_write:
  40. case common_server_errc::er_net_write_interrupted:
  41. case common_server_errc::er_malformed_packet:
  42. case common_server_errc::er_zlib_z_buf_error:
  43. case common_server_errc::er_zlib_z_data_error:
  44. case common_server_errc::er_zlib_z_mem_error: return true;
  45. default: return false;
  46. }
  47. }
  48. else if (cat == get_mysql_server_category() || cat == get_mariadb_server_category())
  49. {
  50. // DB-specific codes are all non fatal
  51. return false;
  52. }
  53. else if (cat == get_client_category())
  54. {
  55. auto code = static_cast<client_errc>(ec.value());
  56. switch (code)
  57. {
  58. // These indicate malformed frames or packet mismatches
  59. case client_errc::incomplete_message:
  60. case client_errc::protocol_value_error:
  61. case client_errc::extra_bytes:
  62. case client_errc::sequence_number_mismatch:
  63. // Exceeding the max buffer size is not recoverable
  64. case client_errc::max_buffer_size_exceeded:
  65. // These are produced by the static interface, and currently cause parsing
  66. // to stop, leaving unread packets in the network buffer.
  67. // See https://github.com/boostorg/mysql/issues/212
  68. case client_errc::metadata_check_failed:
  69. case client_errc::num_resultsets_mismatch:
  70. case client_errc::row_type_mismatch:
  71. case client_errc::static_row_parsing_error:
  72. // While these are currently produced only by the connection pool,
  73. // any timed out or cancelled operation would leave the connection in an undefined state
  74. case client_errc::timeout:
  75. case client_errc::cancelled:
  76. // These are only produced by handshake. We categorize them as fatal because they need reconnection,
  77. // although anything affecting handshake effectively does.
  78. case client_errc::server_doesnt_support_ssl:
  79. case client_errc::unknown_auth_plugin:
  80. case client_errc::server_unsupported:
  81. case client_errc::auth_plugin_requires_ssl: return true;
  82. default: return false;
  83. }
  84. }
  85. else
  86. {
  87. // Other categories are fatal - these include network and SSL errors
  88. return true;
  89. }
  90. }
  91. #endif