chatbot1-2 Exercise 2: What Does Each Status Code Become? =========================================================== ex2.py: from bot.providers.base import error_from_status for status in (400, 401, 402, 403, 404, 413, 429, 500, 502, 503, 504, 529): e = error_from_status(status, "x") print(f"{status} {type(e).__name__:12} retryable={e.retryable}") Run with: py ex2.py Output: 400 BadRequest retryable=False 401 AuthError retryable=False 402 AuthError retryable=False 403 AuthError retryable=False 404 BadRequest retryable=False 413 BadRequest retryable=False 429 RateLimited retryable=True 500 ServerError retryable=True 502 ServerError retryable=True 503 ServerError retryable=True 504 ServerError retryable=True 529 ServerError retryable=True A status I would change (this part is a judgement, not a measured fact): 402, which Anthropic documents as billing_error ("an issue with your billing or payment information"). It is currently an AuthError, the same as a bad key. A bad key is something to fix in configuration; a billing problem is something the person who pays has to fix, and a chatbot should probably tell its operator, not its users. I would add a BillingError (not retryable). What would be affected: error_from_status (one new branch), the errors module (one new class), and the later retry and alerting code in chapter 7, which would treat it as "stop and notify the owner" instead of "check the key". Nothing in the channels or the conversation manager would change, which is the point of having typed errors. WHY THIS WORKS AS AN ANSWER --------------------------- The mapping is the single place where vendor status codes become the bot's own vocabulary, so changing a decision means editing one function. The printed table shows the two properties the rest of the bot depends on: the class (what happened) and retryable (whether trying again could help). Only 429 and the 5xx codes are retryable; 413 is not, because sending the same oversized request again will fail the same way. Note that 529 (Anthropic's "overloaded") is covered by the generic status >= 500 rule, so a vendor-specific code needed no special case.