Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/data-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ component / composable
- it also reports to PostHog error tracking (`trackException`, only
with consent): `ApiValidationError` (field names and issue codes,
never values, record keys or indices), `ApiServerError` (5xx), `ApiNetworkError` (no response) and
`ApiClientError` (429, or a 401 of `/user/refresh/`). Other 4xx and
discarded responses are not reported. Paths are sent as templates
`ApiClientError` (429). Other 4xx (including the 401 of an expired
refresh token) and discarded responses are not reported. Paths are sent as templates
(`src/util/pathTemplate.ts`: `/planning/plan/:uuid/`).
- **Auth** is handled in `src/util/axiosSetup.ts`, which runs from `main.ts`:
- A request interceptor adds `Authorization: Bearer <userStore.accessToken>`.
Expand Down
14 changes: 5 additions & 9 deletions src/lib/apiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ class ApiService {

/**
* Sends contract breaks, server and network errors to error tracking.
* Of the 4xx only 429 and a 401 of the token refresh are sent, and
* never a response discarded for a previous session. Contract breaks,
* server and network errors also go to the backend (Axiom), from every
* user: 429 and the refresh 401 the backend already logs itself.
* Of the 4xx only 429 is sent (an expired refresh token is a normal
* logout), and never a response discarded for a previous session.
* Contract breaks, server and network errors also go to the backend
* (Axiom), from every user: 429 the backend already logs itself.
*
* @private
* @param {unknown} err Error
Expand Down Expand Up @@ -296,11 +296,7 @@ class ApiService {

if (status === undefined) error.name = "ApiNetworkError";
else if (status >= 500) error.name = "ApiServerError";
else if (
status === 429 ||
(status === 401 && path.includes("/user/refresh/"))
)
error.name = "ApiClientError";
else if (status === 429) error.name = "ApiClientError";
else return;

if (status) error.message += ` ${status}`;
Expand Down
11 changes: 2 additions & 9 deletions src/tests/lib/apiService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,21 +320,14 @@ describe("ApiService", () => {
expect(reportClientError).not.toHaveBeenCalled();
});

it("401 of the token refresh", async () => {
it("not a 401 of the token refresh", async () => {
mock.onPost("/user/refresh/").reply(401);

await expect(
apiService.post("/user/refresh/", { id: 1 }, schema, schema)
).rejects.toThrowError();

const { error, props } = tracked();
expect(error.name).toBe("ApiClientError");
expect(props).toStrictEqual({
path_template: "/user/refresh/",
method: "POST",
status: 401,
request_id: expect.stringMatching(UUID),
});
expect(trackException).not.toHaveBeenCalled();
expect(reportClientError).not.toHaveBeenCalled();
});

Expand Down
Loading