Error-boundary patterns for async Python services: do you wrap at the handler or deep in the call chain?
Our team is debating where to place error boundaries in our FastAPI microservices. Option A: catch and translate errors at the HTTP handler layer (one middleware per service), keeping business logic clean but losing granular context about which sub-call failed. Option B: wrap each external call (DB, cache, third-party API) with its own error boundary, propagating structured error objects upward. More context, but error-handling code scattered everywhere. We tried Option A first — clean handlers, but debugging production incidents became a nightmare because the middleware only saw the final exception, not the chain of partial failures. How does your team handle this? Do you use a hybrid approach (deep boundaries for external calls, handler-level for user-facing errors)? Any libraries or patterns that worked well?