Description
Found in backend/handler/passcode.go around line 319: When a passcode expires, the API returns http.StatusRequestTimeout (408), which is semantically incorrect for this use case.
Current Code
businessError = echo.NewHTTPError(http.StatusRequestTimeout, "passcode request timed out").SetInternal(errors.New(fmt.Sprintf("createdAt: %s -> lastVerificationTime: %s", passcode.CreatedAt, lastVerificationTime))) // TODO: maybe we should use BadRequest, because RequestTimeout might be to technical and can refer to different error
Problem
HTTP 408 Request Timeout is meant for situations where:
- The client took too long to send the request
- The server timed out waiting for the request body
- Network/connection issues caused a timeout
It should NOT be used when:
- Application-level validation fails (like an expired passcode)
- Business logic determines something is no longer valid
Impact
- Client confusion: HTTP clients may retry 408 responses automatically, which is inappropriate for expired passcodes
- Monitoring issues: 408s typically indicate infrastructure problems, not application-level validation failures
- API semantics: Violates HTTP specification intent
Recommended Fix
Use a more appropriate status code:
Option 1: 400 Bad Request (Recommended)
businessError = echo.NewHTTPError(http.StatusBadRequest, "passcode has expired").SetInternal(errors.New(fmt.Sprintf("createdAt: %s -> lastVerificationTime: %s", passcode.CreatedAt, lastVerificationTime)))
Option 2: 422 Unprocessable Entity
businessError = echo.NewHTTPError(http.StatusUnprocessableEntity, "passcode has expired").SetInternal(errors.New(fmt.Sprintf("createdAt: %s -> lastVerificationTime: %s", passcode.CreatedAt, lastVerificationTime)))
Location
backend/handler/passcode.go, line ~319 (in the Finish method)
References
Description
Found in
backend/handler/passcode.goaround line 319: When a passcode expires, the API returnshttp.StatusRequestTimeout(408), which is semantically incorrect for this use case.Current Code
Problem
HTTP 408 Request Timeout is meant for situations where:
It should NOT be used when:
Impact
Recommended Fix
Use a more appropriate status code:
Option 1:
400 Bad Request(Recommended)Option 2:
422 Unprocessable EntityLocation
backend/handler/passcode.go, line ~319 (in theFinishmethod)References