Files
cpp-httplib/docs-src/pages/en/cookbook/c17-error-codes.md
T
yhirose 9bfd2ddf1c Fix README and docs pages that no longer match the code
Bring the READMEs and the docs pages (en and ja) in line with the
current header:

- Fix the client sample that does not compile, the Transfer-Encoding
  statement for default headers, the verifier callback comment, the
  thread pool spawn rule, the sanitize_filename description, and the
  inverted Accept-Encoding sentence.
- Describe recent behaviour: TLS errors behind Read/Write failures,
  Host validation, Connection: close for a body without length,
  content_reader rules, refused CONNECT, WebSocketClient proxies,
  CPPHTTPLIB_INTERIM_RESPONSE_MAX_COUNT, the SSE event size limit, and
  the payload limit of the Stream API.
- Complete the API references of WebSocket, WebSocketClient and the
  stream:: helpers, and the SSE reconnect rules.
- Fix cookbook pages: keychain loading on every backend, received Close
  status, a multipart sample that trusted the client's file name, an
  echo sample that sent binary as text, SNI, pre-request handler scope,
  stop() with WebSocket handlers, and the thread pool notes.
- Restore the mutex in the LLM app's Chapter 5 code.
2026-10-18 10:13:57 -04:00

2.6 KiB

title, order, status
title order status
C17. Handle Error Codes 17 draft

cli.Get(), cli.Post(), and friends return a Result. When the request fails — can't reach the server, times out, etc. — the result is "falsy", with one exception noted in the table below. To get the specific reason, use Result::error().

Basic check

httplib::Client cli("http://localhost:8080");
auto res = cli.Get("/api/data");

if (res) {
  // the request was sent and a response came back
  std::cout << "status: " << res->status << std::endl;
} else {
  // the network layer failed
  std::cerr << "error: " << httplib::to_string(res.error()) << std::endl;
}

Use if (res) to check success. On failure, res.error() returns a httplib::Error enum value. Pass it to to_string() to get a human-readable description.

Common errors

Value Meaning
Error::Connection Couldn't connect to the server, or the Client was built from a URL it can't use (userinfo or a backslash in the authority, a bad port). In the latter case cli.is_valid() is false
Error::ConnectionTimeout Connection timeout (set_connection_timeout)
Error::Read / Error::Write Error during send or receive. A timeout from set_read_timeout or set_max_timeout is also reported as Error::Read
Error::Timeout A body read timed out in stream::Get() or SSEClient
Error::ExceedRedirectCount Too many redirects
Error::SSLConnection TLS handshake failed
Error::SSLServerVerification Server certificate verification failed
Error::ProxyConnection The proxy refused the CONNECT tunnel. A 407 is the exception: res is truthy with res->status == 407, and res.error() is still Error::ProxyConnection
Error::Canceled A progress callback, a ContentReceiver, a ResponseHandler, or an upload content provider returned false

Network errors vs. HTTP errors

Even when res is truthy, the HTTP status code can still be 4xx or 5xx. These are two different things.

auto res = cli.Get("/api/data");
if (!res) {
  // network error (no response received at all)
  std::cerr << "network error: " << httplib::to_string(res.error()) << std::endl;
  return 1;
}

if (res->status >= 400) {
  // HTTP error (response received, but the status is bad)
  std::cerr << "http error: " << res->status << std::endl;
  return 1;
}

// success
std::cout << res->body << std::endl;

Keep them separated in your head: network-layer errors go through res.error(), HTTP-level errors through res->status.

To dig deeper into SSL-related errors, see C18. Handle SSL errors.