Module 2 of 9 · Lesson 4 of 26
Organize routes and return consistent errors
Work through organize routes and return consistent errors using a runnable reference, a focused regression check and a local extension.
Read in any order. All lessons stay open, including after an unanswered or incorrect check.
DomainError carries a public code, message and status. A single exception handler turns it into a predictable error envelope. Missing resources produce 404, a capacity conflict produces 409 and a denied action produces 403. FastAPI's request validation has its own 422 format in this reference; document both formats rather than claiming every failure is identical. A database IntegrityError maps to a fixed 409 response without returning SQL or a traceback. A failure contract helps clients decide whether to correct input, authenticate or wait. Internal diagnostic detail belongs in controlled server evidence, never in a raw HTTP error body.
Use the API contract review sheet to write the rental read contract. In api.py locate the handler and rental_read route. The lesson04 check authenticates a synthetic owner, requests a missing UUID and verifies the exact 404 envelope. Compare it with the invalid integer path example from lesson 1.
class DomainError(Exception):
def __init__(self, code, message, status=409):
super().__init__(message)
self.code, self.message, self.status = code, message, status
python run_checks.py -k lesson04
Expected result The selected lesson test passes against a new temporary PostgreSQL database; the container is removed afterward.
Keep for reference
Equipment Rental lab and lesson checks
ZIP containing Python source, real Alembic migrations, 26 lesson checks, a dependency lock and text instructions. Extract it before following the local exercise.
Practise locally
Add a read-only GET /equipment/{id} route that returns EquipmentOut or the existing missing-resource error. Test both paths and write the statuses and response shapes in the worksheet. Keep route functions small and avoid embedding raw database exceptions in the response. If extracting an APIRouter, verify that the generated OpenAPI paths remain unchanged.
The lesson check verifies the reference behavior. Add your own assertions for your change. Local practice is not uploaded or scored by this learning release.
Pause and reflect
What failure does this lesson prevent, and which assertion in lesson04 would expose it?
Use a concrete input, expected result and limitation from your local work. Saving a reflection does not certify the project.
Optional knowledge check
A database uniqueness conflict occurs. What should the caller receive?
A documented conflict status and a safe public message.
Correct. A 409 conflict can explain the outcome without exposing database internals.
The SQL statement, database password and full traceback.
Try another answer. Internal details are not a stable error contract and may reveal sensitive configuration.
Return 200 with an error field so all responses share one status.
Try another answer. The status is part of the failure contract and must convey the failed operation.
This practice does not assess your project or award a certificate.
Keep for reference
API contract review sheet
Optional plain-text worksheet covering methods, inputs, success, deliberate failures and permission scope.
Your reading progress
Progress is saved in this browser when storage is available.