Exceptions and error handling
Đã giới thiệu| English | Ý nghĩa |
|---|---|
| exception/ekˈsepʃn/ | ngoại lệ |
| status value | status value |
The loan that quietly shrank
- A renewal function returns $-1$ when a loan would pass its limit. One caller forgets to check and adds $-1$ to the loan, so a 20-day loan becomes 19 days.
- No error, no message: the failure spread silently. Exceptions exist so that a failure cannot be ignored.
Raise, catch, clean up
- Exceptions 异常 carry an error up to the code that can decide what to do.
raisethrows one;try/exceptcatches it by type. finallyruns on every path, whether the body succeeded or failed.
A small, precise hierarchy
- A custom hierarchy lets callers catch exactly what they can handle: a broad base and specific children. A handler for a parent also catches every child.
class LoanError(Exception): ...
class RenewalError(LoanError): ...
class LimitError(RenewalError): ...
except RenewalError catches a raised LimitError because —
Độ khó 1/5 · 100 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
Handlers match by type through the hierarchy: a parent except catches every child.
except LimitError catches a RenewalError that was raised directly.
Độ khó 1/5 · 100 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
A handler catches its own type and its children. RenewalError is the parent of LimitError, so it passes by.
Check first, raise loudly
renew(Loan(20), 15)checks before changing anything and raisesLimitError('20+15 exceeds 30').- The loan still reads 20. Because a failed call changed nothing, no rollback is needed.
loan = Loan(20). The caller runs renew(loan, 15) inside a try block and catches the LimitError. What does loan.days read afterwards?
Độ khó 2/5 · 140 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
renew checks before changing anything, so the failed call leaves 20.
Unwinding the stack
- A raise leaves the current function and climbs frame by frame, from
renewthroughissueup tomain, running eachfinallyon the way, until anexceptmatches by type. - If nothing matches, the program stops with a traceback: loud, not silent.

Cleanup that always happens
- On the failing path
finallyruns after the handler; on the success path it runs straight after the body. - So cleanup that must happen, such as releasing a lock or closing a file, goes in
finallyor awithblock, never after the last statement.
The finally block runs —
Độ khó 1/5 · 100 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
finally is the cleanup guarantee: it runs after the body, after the handler, before returning.
Status values or exceptions?
- Use a status value 状态值 (such as
Nonefor "not found") for expected outcomes the caller handles right away. - Use an exception for a broken contract or a failure the immediate caller cannot fix.
A returned value of -1 as an error code is dangerous because —
Độ khó 1/5 · 100 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
A normal value enforces nothing; an exception cannot be ignored — it unwinds until handled.
Match each situation to the right tool.
Độ khó 2/5 · 140 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
Expected outcomes return values; broken contracts raise; cleanup goes in finally.
Worked example: cleanup on the failing path
locked = True,loan = Loan(28), thentry: renew(loan, 10)withexcept RenewalError: kept = 'handled'andfinally: locked = False.- $28 + 10 = 38 > 30$, so
renewraises; the handler setskept;finallyunlocks. The loan still reads 28.
In the worked example, renew raises inside the try block. Put what happens in order.
Độ khó 3/5 · 200 xu + phần thưởng nhỏ khi hoàn thành lần đầu tiên hôm nay
The handler runs first, then finally, then normal flow resumes.
Three common slips
- A bare
except:. It even catches Ctrl-C and hides real bugs. except ...: pass. The failure vanishes and the state may be half-changed.- Catching
Exceptionwhen you meant one specific error.
Recap
- Raise on broken contracts; catch where a decision can be made; a parent handler catches its children.
- Check first, so a failed call leaves the state unchanged.
finally(orwith) runs on every path; status values are for expected, nearby outcomes.