C17. エラーコードをハンドリングする
cli.Get()やcli.Post()はResult型を返します。リクエストが失敗したとき(サーバーに到達できなかった、タイムアウトしたなど)、返り値は「falsy」になります。詳しい原因を知りたい場合は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; }
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 | サーバーに接続できなかった |
Error::ConnectionTimeout | 接続タイムアウト(set_connection_timeout) |
Error::Read / Error::Write | 送受信中のエラー |
Error::Timeout | set_max_timeoutで設定した全体タイムアウト |
Error::ExceedRedirectCount | リダイレクト回数が上限を超えた |
Error::SSLConnection | TLSハンドシェイクに失敗 |
Error::SSLServerVerification | サーバー証明書の検証に失敗 |
Error::Canceled | 進捗コールバックから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;
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エラーをハンドリングするを参照してください。