0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🏫11時限目「HTTPステータスコード・エラー処理とは?」【🍞Bakery Hubで学ぶPython・Webアプリ開発】

0
Posted at

4071.png

📌 この記事を3行でまとめると

  • 200・400・403・404・500 などのHTTPステータスコードが何を表しているのか、初心者向けに整理します。
  • Bakery Hubの実コードから、正常な処理とエラー時の処理を読み解きます。
  • return・if・try・except が、Webアプリの中でどのように使われているのか確認します。

🥐 はじめに

こんにちは、tosane932です。

2026年5月からPythonの独学を始め、AIを活用しながらベーカリー向け売上管理アプリ「Bakery Hub」を開発しています。

今回で、Python・Web開発の基礎を学び直すシリーズも 第11時限目 になりました。

前回の第10時限目では、GET・POST・requestについて学びました。

ブラウザからサーバーへリクエストを送り、Flaskが受け取って処理する仕組みです。

今回は、その続きです。

ブラウザからリクエストを送ったあと、サーバーはどうやって処理結果を伝えるのでしょうか。

例えば、商品を登録できた場合と、入力内容が間違っていた場合。

サーバーは、どちらも同じ返事をするのでしょうか。


🐹「商品登録ボタンを押したら、登録完了って表示されたよ!」

🐹「でも、間違った数字を入力したときはエラーが出たんだよね……」

🐹「Pythonは、成功したのか失敗したのかをどうやって伝えてるんだろう?」

今回のテーマは HTTPステータスコードとエラー処理 です。

名前は少し難しそうですが、一つずつ見ていきます。

🥪 今回の教材:Bakery Hub

Bakery Hubは、僕が開発しているベーカリー向け店舗管理アプリです。

商品登録、売上入力、売上分析、店舗メモなどの機能があります。

今回は、商品登録やログインに関係するコードを教材にします。


📖 第1章|HTTPステータスコードって何?

前回学んだGETとPOSTは、ブラウザからサーバーへ送るリクエストでした。

一方、サーバーからブラウザへ返すものをレスポンスと呼びます。

HTTPステータスコードは、そのレスポンスに含まれる3桁の数字です。

処理結果を簡潔に伝える役割があります。

リクエストとレスポンスの流れ

【ブラウザ】

「商品登録画面を見せて!」

       │
       │ GETリクエスト
       ▼

【Flask / サーバー】

商品登録画面を用意する

       │
       │ レスポンス
       │ 200 OK
       ▼

【ブラウザ】

商品登録画面が表示される

🐹「200って数字が返ってきてるんだ!」

HTTPステータスコードの 200 は、一般的にリクエストが成功したことを表します。

ただし、成功や失敗を示す番号は200だけではありません。

例えば、次のようなコードがあります。

ステータスコード 意味 身近なイメージ
200 OK うまく処理できた
400 Bad Request 送られた内容に問題がある
403 Forbidden アクセスを許可できない
404 Not Found 指定されたものが見つからない
500 Internal Server Error サーバー側で問題が起きた

🐹「404は見たことある!存在しないページを開いたときに出るやつだ!」

そうです。

あの404も、HTTPステータスコードの一つだったんですね。

💡 HTTPステータスコードとは?

サーバーがHTTPリクエストに対して返す、3桁の結果コードです。

数字によって、

  • 正常に処理できた
  • 別のページへ移動してほしい
  • リクエストに問題がある
  • サーバー側で問題が起きた

などを伝えます。

参考:MDN|HTTPレスポンスステータスコード


📖 第2章|最初の数字で大まかな意味が分かる

HTTPステータスコードは、最初の数字によってグループ分けされています。

5つのグループ

分類 名前 大まかな意味
1xx 情報レスポンス 処理途中の情報
2xx 成功レスポンス リクエストが成功した
3xx リダイレクト 別の場所への移動など
4xx クライアントエラー リクエスト側に関係する問題
5xx サーバーエラー サーバー側で問題が発生

最初から番号を全部覚える必要はなさそうです。

まずは、次の3つを押さえたいと思います。

2xx → 成功

4xx → リクエストに関係する問題

5xx → サーバー側の問題

🐹「じゃあ400番台と500番台は、問題が起きている場所が違うんだね」

ここが今回、大切なポイントです。

例えば、入力された商品名が条件に合わない場合は400を返すことがあります。

一方、データベースの保存処理で問題が発生した場合は500を返すことがあります。

どちらも登録に失敗していますが、失敗した理由が違うわけです。

📌 4xxは「利用者が悪い」という意味ではない

4xxはクライアントエラーと呼ばれますが、利用者の操作ミスだけを表すものではありません。

アクセス権限の不足や、存在しないURLへのアクセスなども含まれます。

まずは、サーバーが受け取ったリクエストを、そのまま正常に処理できない状態と考えると分かりやすそうです。


📖 第3章|200 OK:正常に処理できた

まずは成功した場合です。

Bakery Hubの商品登録処理では、保存が完了すると次のコードが実行されます。

return render_template(
    "success.html",
    year=year,
    month=month
)

出典:Bakery Hub|app.py

render_template() は、HTMLテンプレートを使って表示する内容を作るFlaskの関数です。

ここでは登録完了画面の success.html を使っています。

コードの役割

コード 意味
render_template() HTMLテンプレートから表示内容を作る
"success.html" 使用するテンプレート
year=year 年の情報を渡す
month=month 月の情報を渡す
return 処理結果を返す

ここには 200 という数字が書かれていません。

実はFlaskでは、正常なレスポンスを返す場合、ステータスコードを省略すると通常は200になります。

🐹「えっ!200って書いてなくても200になるの?」

そうなんです。

ただし、200はHTTPリクエストが成功したことを表すコードなので、どんな処理でもデータベース保存を保証するわけではありません。

今回の商品登録では、保存完了後にこの画面を返す構成になっています。

💡 200は書かなくてもよい場合がある

Flaskでは、通常のレスポンスを返すとき、ステータスコードを省略すると200として扱われます。

そのため、実コードに 200 が見当たらなくても、正常なレスポンスになっている場合があります。

参考:Flask公式|Quickstart


📖 第4章|400 Bad Request:入力に問題がある

次は400です。

Bakery Hubの商品登録では、登録する年月もフォームから送信しています。

例えば、1〜12月の範囲で指定する月に、13という数字が送られてきたらどうなるでしょうか。

実際のコードを見てみます。

if month < 1 or month > 12:
    logger.warning("Rejected product update with out-of-range month.")
    return "月は1から12で指定してください。", 400

🐹「あっ!ここに400がある!」

ここでは、月が1未満または12を超えているかを確認しています。

条件を分解してみる

month < 1 or month > 12
条件 意味
month < 1 1未満か
or どちらかの条件が成立するか
month > 12 12を超えているか

例えば、

month = 13

なら、

13 < 1 or 13 > 12

となります。

右側の条件が True なので、if 文の中へ進みます。

そして、このreturn

return "月は1から12で指定してください。", 400

ここには、文字列と数字があります。

部分 役割
"月は1から12で指定してください。" レスポンスとして返すメッセージ
400 HTTPステータスコード

Flaskでは、このようにタプルの形でレスポンスの内容とステータスコードを指定できます。

🐹「なるほど!画面に表示する言葉と、HTTPの結果を一緒に返してるんだ!」

つまり、400は「入力が間違っています」といった状況を、HTTPの仕組みとして伝える役割を持っています。

📚 Python基礎とのつながり

今回登場したのは、

  • if:条件分岐
  • <・>:比較演算子
  • or:論理演算子
  • return:結果を返す

です。

以前学んだ文法が、入力値の検証に使われています。


📖 第5章|403と404の違い

ここで、少し似ているように感じる2つの番号を見てみます。

403 Forbidden

403は、アクセスを許可できない場合に使われます。

Bakery Hubには、利用者がアクセスできるデータを確認する処理があります。

その一部です。

if not current_user.is_authenticated:
    abort(403)

出典:Bakery Hub|app.py

ここでは、認証されていない場合に403を発生させています。

abort() は、Flaskで指定したHTTPエラーを発生させるための関数です。

🐹「return ..., 400 とは書き方が違うんだね」

そうですね。

HTTPステータスコードを指定する方法は一つではありません。

今回は、

  • return "メッセージ", 400
  • abort(403)

という2種類の書き方が登場しました。

404 Not Found

一方の404は、指定されたページなどが見つからない場合です。

例えば、存在しないURLにアクセスしたとします。

GET /not-found-page

FlaskでそのURLを処理するルートが存在しなければ、通常は404が返されます。

403と404を比較

コード 状況の例
403 アクセスを許可できない
404 指定されたページが見つからない

🐹「403はアクセスできない、404は見つからない、って覚えると分かりやすいね」

なお、未ログイン状態を示すときなどには401が使われる場合もあります。

403との細かな違いは、認証や権限管理を学ぶときに改めて確認したいと思います。


📖 第6章|500 Internal Server Error:サーバー側の問題

次は500です。

400番台がリクエストに関係する問題だったのに対し、500番台はサーバー側の問題を表します。

例えば、商品を登録しようとしたとき、データベースへの保存に失敗する場合があります。

Bakery Hubには、次のような処理があります。

実コードから一部を抜粋

try:
    # 商品の追加や更新などの処理(途中省略)

    db.session.commit()

except SQLAlchemyError:
    db.session.rollback()
    logger.exception("Failed to save product master.")
    return "商品マスタを保存できませんでした。", 500

※ 学習しやすいように、try 内の途中の処理を省略しています。

🐹「今度は try と except が出てきた!」

以前のPython基礎でも、例外処理について学びました。

ここでは、データベースへの保存などでSQLAlchemyの例外が発生した場合に、except SQLAlchemyError の処理へ進むようになっています。

コードを分けてみる

コード 役割
try 例外が発生する可能性のある処理を実行する
db.session.commit() DBへの変更を確定する
except SQLAlchemyError 指定した種類の例外を捕まえる
db.session.rollback() 未確定の変更を取り消す
logger.exception() エラー情報をログに残す
return ..., 500 保存失敗をHTTPの結果として返す

なぜrollbackするのか?

例えば、3つの商品をまとめて登録するとします。

クロワッサン
あんぱん
食パン

途中で保存に失敗した場合、変更が中途半端な状態になってしまうと困ります。

そこで、rollback() によって未確定の変更を取り消します。

🐹「つまり、保存できなかったときの対応もコードに書いてあるんだ!」

そうなんです。

ただ成功する処理だけではなく、失敗した場合にどうするかも考える必要があります。

⚠️ 500は必ずデータベースのエラーとは限らない

500は、サーバー側で問題が発生したことを表す一般的なステータスコードです。

原因はデータベースに限りません。

今回はBakery Hubの保存失敗処理を例にしています。

また、except SQLAlchemyError はすべての例外を捕まえるわけではなく、対象となる例外の種類が決まっています。


📖 第7章|例外とHTTPステータスコードは同じもの?

ここまで読んで、もう一つ疑問が出てきました。

🐹「except でエラーを捕まえるのと、400や500を返すのって同じこと?」

実は、別の仕組みです。

2つの違い

項目 役割
Pythonの例外 プログラムの処理中に起きた問題を知らせる
HTTPステータスコード HTTPリクエストに対する結果を相手へ伝える

例えば、商品の月が13だった場合。

これはアプリが想定している入力条件に合っていません。

でも、Pythonの例外が発生しなくても、if 文で判定して400を返せます。

一方、データベース操作中に例外が発生したら、except で捕まえたあとに500を返すことがあります。

【入力値が条件に合わない】

if文で検証
     ↓
400を返す


【データベース処理で例外が発生】

try内で例外発生
     ↓
exceptで捕まえる
     ↓
rollback()
     ↓
500を返す

🐹「なるほど!Pythonの例外を扱うことと、ブラウザへ結果を知らせることは別なんだね」

僕も最初は、どちらも「エラー」という言葉でまとめて考えていました。

でも役割を分けてみると、少し整理できました。


📖 第8章|302って何? エラーじゃないの?

ここまで200・400・403・404・500を見てきました。

最後に、もう一つだけ紹介します。

302 Found です。

302はエラーではなく、別のURLへの移動を案内するために使われるステータスコードです。

Bakery Hubのログアウト処理には、次のコードがあります。

return redirect(url_for("login"))

redirect() は、指定したURLへ移動するためのレスポンスを作ります。

Flaskの redirect() は、ステータスコードを指定しなければ通常302を使います。

ログアウト後の流れ

ログアウト
    │
    ▼
Flaskがログアウト処理を実行
    │
    ▼
302 リダイレクト
    │
    ▼
ブラウザがログイン画面へ移動

🐹「302はエラーじゃなくて、別のページへ案内する番号なんだ!」

ステータスコードは、失敗したときだけに使うものではありません。

正常な処理やページ移動にも使われているんですね。


📖 第9章|ステータスコードをまとめて整理

今回学んだものを表にまとめてみます。

コード 意味 Bakery Hubでの例
200 正常に処理できた 商品登録完了画面を表示
302 別のURLへ案内する ログアウト後にログイン画面へ移動
400 リクエストの内容に問題がある 月に13を指定した
403 アクセスを許可できない 利用者の認証条件を満たしていない
404 見つからない 存在しないページへのアクセス
500 サーバー側の問題 DB保存時にエラーが発生した

最初からすべての番号を暗記するより、

まずは最初の数字から、大まかな原因を推測できるようになりたいと思います。

200 → 成功した

302 → 別のURLへ移動する

400 → リクエスト内容に問題がある

403 → アクセスを許可できない

404 → 見つからない

500 → サーバー側に問題がある

🐹「404しか知らなかったけど、ほかの番号にもちゃんと意味があったんだね」


📝 第11時限目の理解度チェック

今回も、最後に5問で復習します。

まずは答えを見ずに考えてみます。

問題 内容
Q1 HTTPステータスコードは、リクエストとレスポンスのどちらに含まれる?
Q2 正常に処理できたことを示す代表的なコードは?
Q3 存在しないページにアクセスしたときの代表的なコードは?
Q4 400番台と500番台の大まかな違いは?
Q5 except SQLAlchemyError と return ..., 500 は同じ役割?
✅ 解答例を見る

Q1. HTTPステータスコードはどちらに含まれる?

レスポンスです。

サーバーからブラウザへ、リクエストの処理結果を伝えます。

Q2. 正常に処理できたことを示す代表的なコードは?

200 OK です。

Q3. 存在しないページにアクセスしたときは?

404 Not Found です。

Q4. 400番台と500番台の違いは?

400番台はリクエストに関係する問題、500番台はサーバー側の問題を表します。

Q5. 同じ役割?

違います。

except SQLAlchemyError はPythonで特定の例外を捕まえる処理です。

return ..., 500 はHTTPレスポンスとして500を返します。


🐹 おわりに

今回は、HTTPステータスコードとエラー処理について学び直しました。

これまで404や500という数字を見たことはありましたが、正直なところ、それぞれ何が違うのか深く考えたことはありませんでした。

でも、Bakery Hubのコードを読んでみると、番号によって意味が違うことが分かりました。

特に印象に残ったのは、Pythonの例外処理とHTTPステータスコードは別の役割を持っているということです。

今まではどちらも「エラー処理」としてまとめて考えがちでした。

実際には、

  • Pythonが問題を検知する
  • 必要なら変更を取り消す
  • HTTPレスポンスで結果を知らせる

という役割があります。

もちろん、今回の記事だけでエラー処理をすべて理解できたわけではありません。

HTTPステータスコードには、まだまだたくさんの種類があります。

ただ、400や500を見たときに、以前より少しは原因を考えられそうです。

🐹「404はページがない、400は送った内容に問題がある、500はサーバー側の問題……」

🐹「全部同じエラーじゃなかったんだね!」

これからもBakery Hubのコードを読みながら、知っているつもりだった基礎を、一つずつ理解し直していきたいと思います。

最後まで読んでいただき、ありがとうございました!


🔗 参考資料・関連リンク

公式ドキュメント

🐹 Python基礎シリーズ|これまでの学習記録

Bakery Hub(旧sales_data_app)の実コードを教材に、Pythonの基本文法からWeb開発の仕組みまで学び直しています。

時限 学習テーマ 記事
第1時限目 変数・データ型・比較演算子・if文 📖 読む
第2時限目 リスト・辞書・set・for文 📖 読む
第3時限目 関数・引数・return・型ヒント 📖 読む
第4時限目 モジュール・import・例外・try・except 📖 読む
第5時限目 クラス・インスタンス・init・self・属性 📖 読む
第6時限目 f文字列・アンパック・内包表記・join 📖 読む
第7時限目 strip・len・splitlines・スライス 📖 読む
第8時限目 None・is・is not・isinstance 📖 読む
第9時限目 CRUD・Create・Read・Update・Delete 📖 読む
第10時限目 GET・POST・request 📖 読む
第11時限目 HTTPステータスコード・エラー処理 📍 今回の記事

🥐 Bakery Hub

GitHub|Tosane Works

Bakery Hub|公開デモ

システム概要|実コードで学ぶページ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?