5 - API (feat): Improved Errors#230
Merged
Merged
Conversation
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
from
July 10, 2026 14:13
c12837f to
bd0db2e
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 10, 2026 14:13
ea9ed06 to
4ca4f6e
Compare
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
from
July 10, 2026 14:20
bd0db2e to
934a15f
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 10, 2026 14:20
4ca4f6e to
02a5f78
Compare
CammilleCC
approved these changes
Jul 13, 2026
CammilleCC
left a comment
Member
There was a problem hiding this comment.
Comment aside, LGTM. Error codes and exception names make sense.
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 17, 2026 06:20
02a5f78 to
c60b40f
Compare
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
2 times, most recently
from
July 17, 2026 06:21
d3b6985 to
0a44707
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 17, 2026 06:21
c60b40f to
c80d085
Compare
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
from
July 17, 2026 08:40
0a44707 to
9288103
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
2 times, most recently
from
July 17, 2026 09:09
0ddd29c to
c9d9daf
Compare
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
2 times, most recently
from
July 17, 2026 09:11
d15702f to
7b7216a
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 17, 2026 09:11
c9d9daf to
4c5700c
Compare
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
from
July 17, 2026 09:12
7b7216a to
92d115c
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
2 times, most recently
from
July 17, 2026 09:12
bf4af8b to
bce3ee7
Compare
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
2 times, most recently
from
July 17, 2026 10:46
22719a6 to
a454529
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
2 times, most recently
from
July 17, 2026 11:01
04f2042 to
951da6d
Compare
RobertRosca
marked this pull request as ready for review
July 17, 2026 12:00
Member
|
LGTM after CI and the rename |
RobertRosca
force-pushed
the
feat/api-e2e-rec-tests
branch
from
July 20, 2026 09:25
3967e92 to
9dd4463
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 20, 2026 09:26
951da6d to
08d0c88
Compare
RobertRosca
force-pushed
the
feat/improved-api-errors
branch
from
July 20, 2026 09:28
08d0c88 to
349cfa2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR no. 5 of the big refactor.
This PR expands on the
DWErrorexception, creating a few explicitErrors based on that which should be used throughout the application code whenever an error/failure needs to be raised to be shown to the client, and adds in code to handle the errors at the request 'edge' (rest, graphql) so that the right response is sent to the client.Details
Previously the API used builtin/re-raised exceptions, which makes it hard to tell if an error is 'expected' (missing proposal, upstream service, permission denial, etc...) or not (random bug in our code/a dependency, divide by zero, unexpected
None, etc...), which makes it harder to dispatch to the right handler.ADR-001 explains this in more detail and says that there should be an easy way to figure out what error response to send to a client, and decides to do this by having some distinct error classes where this happens, with anything else mapped to generic 500 error. To keep things from going very out of control, mapping to a response should be done in one clear place (transport edge/handler).
Error Classes
Errors are in
shared/errors.py. The errors are meant to be framework-agnostic/generic-ish, so they aren't subclasses of some specific FastAPI/Starlette/Strawberry/whatever class.Instead all errors are based on the main error class,
DWError, which has fields:code: defaults to 500, so it's always definedmessagedetailsrequest_id- captured from structlog contextvars at raise timeCurrently the following errors are defined:
InvalidInputError(400)UnauthenticatedError(401)ForbiddenError(403)NotFoundError(404)ProposalNotFoundErrorUpstreamServiceError(502), e.g. MyMdC/Keycloak not availableDataUnavailableError(503), e.g. issue reading data files (runs.sqlite, hdf5)Mapping
REST maps a
DWErrorto{"message", "details", "request_id"}withexc.codevia a FastAPI exception handler.According to the ADR, GraphQL maps
DWErrors as GraphQL errors withextensions: {code, request_id}so the frontend branches oncoderather than message text.This is a partial lie since that's not in this PR/branch and is included in a later branch in the stack that changes the resolvers, but that's the design.
Tests
test_errors.pycovers:codeattributesProposalNotFoundError->NotFoundErrorinheritancedetails/request_idcapture (including the unbound-contextvars case)DWErrorto the right status code and body