unilink  0.4.3
A simple C++ library for unified async communication
error_mapping.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Jinwoo Sung
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <boost/asio/error.hpp>
20 #include <boost/system/error_code.hpp>
21 #include <optional>
22 #include <string>
23 
27 
28 namespace unilink {
29 namespace diagnostics {
30 
34 inline ErrorCode to_unilink_error_code(const boost::system::error_code& ec) {
35  if (!ec) {
36  return ErrorCode::Success;
37  }
38 
39  // Check specific boost error codes
40  if (ec == boost::asio::error::connection_refused) {
42  }
43  if (ec == boost::asio::error::timed_out) {
44  return ErrorCode::TimedOut;
45  }
46  if (ec == boost::asio::error::connection_reset) {
48  }
49  if (ec == boost::asio::error::connection_aborted) {
51  }
52  if (ec == boost::asio::error::network_unreachable || ec == boost::asio::error::host_unreachable) {
54  }
55  if (ec == boost::asio::error::already_connected) {
57  }
58  if (ec == boost::asio::error::address_in_use) {
59  return ErrorCode::PortInUse;
60  }
61  if (ec == boost::asio::error::access_denied) {
63  }
64 
65  // Fallback to generic IoError for other network errors
66  return ErrorCode::IoError;
67 }
68 
72 inline bool is_retryable_tcp_connect_error(const boost::system::error_code& ec) {
73  if (!ec) return false;
74 
75  // Connection refused is temporary (server might be starting up)
76  if (ec == boost::asio::error::connection_refused) return true;
77  // Timeouts are temporary network glitches
78  if (ec == boost::asio::error::timed_out) return true;
79  // Reset connection might be temporary
80  if (ec == boost::asio::error::connection_reset) return true;
81  // Unreachable might be temporary routing issue
82  if (ec == boost::asio::error::network_unreachable || ec == boost::asio::error::host_unreachable) return true;
83  // Resource temporarily unavailable
84  if (ec == boost::asio::error::try_again) return true;
85 
86  // Aborted usually means stopped by user, not retryable automatically
87  if (ec == boost::asio::error::operation_aborted) return false;
88 
89  // Default to true for unknown errors in network context to be resilient?
90  // Or false? The requirement says "PR2는 보수적으로 true로 둬도 됨" (conservative to keep retrying)
91  return true;
92 }
93 
98  std::optional<size_t> client_id = std::nullopt) {
100 
101  if (info.boost_error) {
102  code = to_unilink_error_code(info.boost_error);
103  } else {
104  // Map category if boost error is not present
105  switch (info.category) {
108  break;
111  break;
114  break;
115  default:
116  code = ErrorCode::IoError;
117  break;
118  }
119  }
120 
121  // Use the message from ErrorInfo
122  return wrapper::ErrorContext(code, info.message, client_id);
123 }
124 
125 } // namespace diagnostics
126 } // namespace unilink