What “type safety” could you possibly hope for from a system you don’t control?
I’m not even sure where to start from that. Responses provided to an HTTP request are one of the most obvious places where enforcing structure and type safety is clearly a win.
try:
val = input['foo']['bar']
except KeyError, TypeError:
raise HttpErrors.BadRequestif 'bar' in input['foo'].keys(): val = input['foo']['bar']
Generally, exceptions cause code to run slower and I feel like in any other language is considered bad practices.
I never understood why Python promotes EAFP vs LBYL. Both performance and accuracy wise, checking before doing is safer and faster performance.
Python exceptions are only slower on the exception. They are almost exactly the same speed on success.
LBYL forces you to look for all the ways in which you might leap. EAFP lets you handle even unexpected conditions. The classic use case is checking if a condition exists, then doing the thing, except the condition changed between check and run. So you gotta catch anyways.
I've been moving away from this actually and towards a rust-like Result[T, Exception]. I'm using the package called "result". For fastapi api_request -> handler -> some_func_chain -> return response_to_client patterns, if something barfs, you normally get a 422 and useless "Internal server error". It's far simpler imho to map over some Results and then pack the error(s) into a more useful response.
Also testing is just a lot simpler.
Also, in Go, using panic/recover is considered unidiomatic. You can use it like an exception system, but it's not what you're supposed to do.
You receive some bytes and you do stuff with them. Any other expectation is a farce.
Is a property missing after serialization? Can you even serialize it? Maybe a different status code returns a different mime type! OK, whatever. That’s not always an error, nor is it remotely “exceptional.”