mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
A buffered request whose response body went over set_payload_max_length(), also once decompressed, failed with Error::Read, while the Stream API reports the same limit as Error::ExceedMaxPayloadSize. read_content() already marks it with a 413 status, so map that status to ExceedMaxPayloadSize next to the 415 and 500 the client maps already.
3.3 KiB
3.3 KiB
title, order, status
| title | order | status |
|---|---|---|
| C17. エラーコードをハンドリングする | 17 | draft |
cli.Get()やcli.Post()はResult型を返します。リクエストが失敗したとき(サーバーに到達できなかった、タイムアウトしたなど)、返り値は「falsy」になります(例外が1つあり、下の表で説明します)。詳しい原因を知りたい場合はResult::error()を使います。
基本の判定
httplib::Client cli("http://localhost:8080");
auto res = cli.Get("/api/data");
if (res) {
// リクエストが送れて、レスポンスも受け取れた
std::cout << "status: " << res->status << std::endl;
} else {
// ネットワーク層で失敗した
std::cerr << "error: " << httplib::to_string(res.error()) << std::endl;
}
if (res)で成功・失敗を判定し、失敗時はres.error()でhttplib::Error列挙値を取り出せます。to_string()に渡すと人間が読める文字列になります。
代表的なエラー
| 値 | 意味 |
|---|---|
Error::Connection |
サーバーに接続できなかった。または、使えないURL(authorityにuserinfoやバックスラッシュがある、ポートが不正など)からClientを作った。後者の場合はcli.is_valid()がfalseになる |
Error::ConnectionTimeout |
接続タイムアウト(set_connection_timeout) |
Error::Read / Error::Write |
送受信中のエラー。set_read_timeoutやset_max_timeoutによるタイムアウトもError::Readになる |
Error::ExceedMaxPayloadSize |
レスポンスボディがset_payload_max_length()の上限を超えた(解凍後に超えた場合も含む) |
Error::Timeout |
stream::Get()やSSEClientで、ボディの読み取りがタイムアウトした |
Error::ExceedRedirectCount |
リダイレクト回数が上限を超えた |
Error::SSLConnection |
TLSハンドシェイクに失敗 |
Error::SSLServerVerification |
サーバー証明書の検証に失敗 |
Error::ProxyConnection |
プロキシがCONNECTのトンネルを拒否した。ただし407は例外で、resはtruthyかつres->status == 407になり、res.error()はError::ProxyConnectionのまま |
Error::Canceled |
進捗コールバック、ContentReceiver、ResponseHandler、アップロード用のコンテンツプロバイダのいずれかからfalseが返された |
ステータスコードとの使い分け
resがtruthyでも、HTTPステータスコードが4xxや5xxのこともあります。この2つは別物です。
auto res = cli.Get("/api/data");
if (!res) {
// ネットワークエラー(そもそもレスポンスを受け取れていない)
std::cerr << "network error: " << httplib::to_string(res.error()) << std::endl;
return 1;
}
if (res->status >= 400) {
// HTTPエラー(レスポンスは受け取った)
std::cerr << "http error: " << res->status << std::endl;
return 1;
}
// 正常系
std::cout << res->body << std::endl;
ネットワーク層のエラーはres.error()、HTTPのエラーはres->status、と頭の中で分けておきましょう。
SSL関連のエラーをさらに詳しく調べたい場合はC18. SSLエラーをハンドリングするを参照してください。