Skip to content

Improve error handling of responses - #821

Open
robbevp wants to merge 4 commits into
mainfrom
enhc/improve-resolve-error-handling
Open

Improve error handling of responses#821
robbevp wants to merge 4 commits into
mainfrom
enhc/improve-resolve-error-handling

Conversation

@robbevp

@robbevp robbevp commented Jul 12, 2026

Copy link
Copy Markdown
Member

This PR improves the way we handle errors in resolve. This should help clients to distinguish between the different errors and handle each in a specific way.

  • We add types for the structured errors returned from the API (both our own and a general one for rails' default error handling)
  • We add our own error classes, each representing an HTTP status code, to match our structured errors
  • We add a type and error class for error that are handled by rails. I based the type on 2/3 examples (but left out the traces, as these won't be there in production anyway)
  • We only try to parse the response body if we known that it's json
  • Each error thrown inside resolve is now a subclass of Error, following the advice on MDN

I didn't really add tests now, but I have an idea for more extensive tests for the api client (using VCR like recordings) - I'd rather do that then create a bunch of tests that write out a reponses by hand

@robbevp robbevp self-assigned this Jul 12, 2026
@robbevp robbevp added the enhancement New feature or request label Jul 12, 2026
@robbevp
robbevp force-pushed the enhc/improve-resolve-error-handling branch from 6dd6a2b to 3727d7d Compare July 12, 2026 11:46
@robbevp
robbevp force-pushed the enhc/improve-resolve-error-handling branch from 3727d7d to 60970d0 Compare July 12, 2026 11:47
@robbevp

robbevp commented Jul 12, 2026

Copy link
Copy Markdown
Member Author

@chvp I'll leave this as a draft until I have a matching PR in the web client. I imagine some details might still change while working on the web side, but this should generally be good for a first review

@robbevp
robbevp marked this pull request as ready for review July 25, 2026 12:11
@robbevp
robbevp requested a review from chvp as a code owner July 25, 2026 12:11
Comment thread src/http.ts

// If the body isn't json, we throw an error with the body parsed as plain text
const contentType = response.headers.get("Content-Type");
if (contentType === null || !contentType?.startsWith("application/json")) {

@robbevp robbevp Jul 25, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a naive way of checking this. Maybe we should properly parse this header and check the value?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, seems fine to me.

Comment thread src/errors.ts
Comment on lines +77 to +87
export class UnknownError extends Error {
details?: unknown;

constructor(message: unknown, details?: unknown) {
super(`${message}`);
this.name = "UnknownError";
this.details = details;
}
}

export class UnexpectedError extends Error {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to distinguish between:

  • The rails API returns an error that we didn't explicitly send (fe a 500 internal server error)
  • We get an error that we truly don't know what to do with (fe. getting a non-json body)

I don't think this is the best potential naming, but it's what I could come up with

Comment thread src/http.ts
const reason: Record<string, string[]> = {};
if (error instanceof Error) {
reason[error.constructor.name] = [error.message];
throw error;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, we might want to check the content of these errors and return custom types that wrap these so that it's easier to handle them in the client (for example with an OfflineError)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I did that at work in the recent past, it's quite nice to do this (since otherwise it's just a TypeError in most browsers).

Comment thread src/errors.ts
errors: Array<AnyError>;
};

export type AnyError =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export type AnyError =
export type AnyErrorMessage =

? Since this isn't a subclass of Error this feels a bit nicer to me.

Comment thread src/http.ts

// If the body isn't json, we throw an error with the body parsed as plain text
const contentType = response.headers.get("Content-Type");
if (contentType === null || !contentType?.startsWith("application/json")) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, seems fine to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants