> Many levels of try/except nesting could
At least to me, this is an anti-pattern in any language that supports try-catch type error handling.Many levels of try-catch should almost always be eliminated except for a small handful of use cases.
Unless you 1) can recover, 2) can retry, 3) need to log some local context, 4) need to transform the lower level error (including transforming it for display purposes), my heuristic is that it should always be handled at the highest level possible in the stack and just let the exception pass through.
But generally, for the user, I posit that it should still be handled at the highest level of granularity and the message returned to the user on an error should be similarly high level.
I try to use exception chaining to create a message that is useful for the user to actually debug the problem (solution-directed error message).
The classic toy case is either getting back "permission denied" or "can not open foo" but not both. Chaining of error messages gives a straightforward mechanism for this.
Then, the high-level text, along with the caused-by messages, is displayed without a stack trace to hopefully give the user enough information to address an issue.
Chaining can be done with explicitly returned errors as well as exceptions. The hard part is actually thinking about "is this use to the end user"