Learning Objectives
- Understand the HTTP 500 error class and what triggers it on the server side
- Distinguish between client errors (4xx) and server errors (5xx) from a testing perspective
- Trace the path from a thrown exception to an HTTP 500 response in a web framework
The 5xx Error Class
HTTP status codes in the 500–599 range indicate that the server received a valid request but failed to fulfill it due to an internal error. Unlike 4xx errors (where the client sent something wrong), 5xx errors mean the server was unprepared for what it received — a bug.
| Code | Name | Typical Cause |
|---|---|---|
| 500 | Internal Server Error | Unhandled exception, bug in server code |
| 502 | Bad Gateway | Upstream service returned an invalid response |
| 503 | Service Unavailable | Server overloaded or down for maintenance |
| 504 | Gateway Timeout | Upstream service took too long to respond |
As a tester, you will most commonly encounter 500. It is the catch-all for "something unexpected happened in the server code."
What Triggers a 500
A 500 response is generated when server code throws an exception that is not caught and handled. Common triggers include:
- NullPointerException: accessing a field on a null object (e.g., date field not populated)
- ArithmeticException: division by zero in a date-based rate calculation
- DateTimeParseException: a malformed date string passed to a parser
- StackOverflowError: infinite recursion in date generation logic
- OutOfMemoryError: generating too many dates at once (e.g.,
from 1900-01-01 to 2100-01-01daily) - ClassCastException: a date value returned as the wrong type from a database
How Frameworks Wrap Exceptions into HTTP Responses
Modern web frameworks intercept unhandled exceptions before they reach the client and translate them into HTTP responses:
1. Request arrives: POST /bookings with body {"checkin": "2024-03-31", "checkout": "2024-03-31"}
2. Controller method executes date arithmetic: checkout - checkin = 0 days
3. Service divides total cost by 0 → ArithmeticException thrown
4. Exception propagates up the call stack (no catch block catches it)
5. Framework's global exception handler catches it
6. Framework generates HTTP 500 response:
- Dev mode: includes stack trace in response body
- Production mode: returns generic {"error": "Internal server error"} + error ID
400 vs 500: A Critical Distinction
| Scenario | Status | Meaning |
|---|---|---|
User enters abc in a date field; server validates and rejects |
400 | Server handled it correctly |
User enters abc in a date field; server tries to parse it and crashes |
500 | Bug: server should have validated first |
| User enters valid dates but triggers a division-by-zero | 500 | Bug: server did not guard against this input combination |
From a quality perspective: a 400 response to invalid input is expected behavior. A 500 response to any input — valid or invalid — is always a bug. The server should never crash regardless of what the user sends.