mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
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.
2.6 KiB
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.