Skip to content

Commit 71dcebe

Browse files
meili-bors[bot]flevi29brunoocasali
authored
Merge #1656
1656: Improve errors r=curquiza a=flevi29 # Pull Request ## Related issues Fixes #1612, #1655 ## What does this PR do? This PR aims to improve errors, so that they can contain all the necessary information, and more. - Prevent browser test `jsdom` from replacing `fetch` and `AbortController` for consistency with node tests, replacing previous solution where we removed the builtin `fetch` from node tests - Remove `"abort-controller"` package, it was only used in tests and now `AbortController` is always available - Rename `MeiliSearchCommunicationError` to `MeiliSearchRequestError`, as this error might not be entirely related to communication, but rather the request itself - Make errors use [`cause`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause), preserving the original error, simplifying things, taking advantage of modern browsers and runtimes actually printing this property - Remove the use of `Object.setPrototypeOf` in errors, this is not needed in modern browsers, and bundlers take care of it if we need to support older browsers (so in UMD bundle it's done twice currently). (https://stackoverflow.com/a/76851585) - Remove the use of `Error.captureStackTrace`, this is done by the base `Error` constructor, and it's only available in V8 engine based browsers/runtimes - https://v8.dev/docs/stack-trace-api - https://nodejs.org/api/errors.html#new-errormessage-options - https://stackoverflow.com/a/64063868 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack - Only catch the error from `fetch` to re-throw it as `MeiliSearchRequestError`, other potential errors should propagate as they're either truly unexpected or are thrown by us, simplifying error handling and not putting unexpected errors under the `MeiliSearchError` umbrella - Rename `MeiliSearchErrorInfo` type to `MeiliSearchErrorResponse` - Other minor changes/improvements NOTE: Tests are horrifying, I didn't change all that much in src, but I had to change almost every test and by quite a bit. Testing is what I should aim to improve ASAP. Co-authored-by: F. Levi <[email protected]> Co-authored-by: Bruno Casali <[email protected]>
2 parents 01f51b4 + 4b3dc78 commit 71dcebe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+437
-793
lines changed

jest-disable-built-in-fetch.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

jest.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const config = {
1616
'jest-watch-typeahead/filename',
1717
'jest-watch-typeahead/testname',
1818
],
19-
globalSetup: './jest-disable-built-in-fetch.js',
2019
projects: [
2120
{
2221
preset: 'ts-jest',
@@ -28,6 +27,8 @@ const config = {
2827
'env/',
2928
'token.test.ts',
3029
],
30+
// make sure built-in Node.js fetch doesn't get replaced for consistency
31+
globals: { fetch: global.fetch, AbortController: global.AbortController },
3132
},
3233
{
3334
preset: 'ts-jest',

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@
8484
"@types/jest": "^29.5.11",
8585
"@typescript-eslint/eslint-plugin": "^6.19.0",
8686
"@typescript-eslint/parser": "^6.19.0",
87-
"abort-controller": "^3.0.0",
8887
"brotli-size": "^4.0.0",
8988
"eslint": "^8.56.0",
9089
"eslint-config-prettier": "^9.1.0",

src/errors/http-error-handler.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/errors/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
export * from './http-error-handler';
21
export * from './meilisearch-api-error';
3-
export * from './meilisearch-communication-error';
2+
export * from './meilisearch-request-error';
43
export * from './meilisearch-error';
54
export * from './meilisearch-timeout-error';
65
export * from './version-hint-message';
Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
1-
import { MeiliSearchErrorInfo } from '../types';
1+
import { MeiliSearchErrorResponse } from '../types';
22
import { MeiliSearchError } from './meilisearch-error';
33

4-
const MeiliSearchApiError = class extends MeiliSearchError {
5-
httpStatus: number;
6-
code: string;
7-
link: string;
8-
type: string;
9-
stack?: string;
4+
export class MeiliSearchApiError extends MeiliSearchError {
5+
override name = 'MeiliSearchApiError';
6+
override cause?: MeiliSearchErrorResponse;
7+
readonly response: Response;
108

11-
constructor(error: MeiliSearchErrorInfo, status: number) {
12-
super(error.message);
9+
constructor(response: Response, responseBody?: MeiliSearchErrorResponse) {
10+
super(
11+
responseBody?.message ?? `${response.status}: ${response.statusText}`,
12+
);
1313

14-
// Make errors comparison possible. ex: error instanceof MeiliSearchApiError.
15-
Object.setPrototypeOf(this, MeiliSearchApiError.prototype);
14+
this.response = response;
1615

17-
this.name = 'MeiliSearchApiError';
18-
19-
this.code = error.code;
20-
this.type = error.type;
21-
this.link = error.link;
22-
this.message = error.message;
23-
this.httpStatus = status;
24-
25-
if (Error.captureStackTrace) {
26-
Error.captureStackTrace(this, MeiliSearchApiError);
16+
if (responseBody !== undefined) {
17+
this.cause = responseBody;
2718
}
2819
}
29-
};
30-
export { MeiliSearchApiError };
20+
}

src/errors/meilisearch-communication-error.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/errors/meilisearch-error.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
class MeiliSearchError extends Error {
2-
constructor(message: string) {
3-
super(message);
1+
export class MeiliSearchError extends Error {
2+
override name = 'MeiliSearchError';
43

5-
// Make errors comparison possible. ex: error instanceof MeiliSearchError.
6-
Object.setPrototypeOf(this, MeiliSearchError.prototype);
7-
8-
this.name = 'MeiliSearchError';
9-
10-
if (Error.captureStackTrace) {
11-
Error.captureStackTrace(this, MeiliSearchError);
12-
}
4+
constructor(...params: ConstructorParameters<typeof Error>) {
5+
super(...params);
136
}
147
}
15-
16-
export { MeiliSearchError };
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { MeiliSearchError } from './meilisearch-error';
2+
3+
export class MeiliSearchRequestError extends MeiliSearchError {
4+
override name = 'MeiliSearchRequestError';
5+
6+
constructor(url: string, cause: unknown) {
7+
super(`Request to ${url} has failed`, { cause });
8+
}
9+
}
Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
import { MeiliSearchError } from './meilisearch-error';
22

3-
class MeiliSearchTimeOutError extends MeiliSearchError {
3+
export class MeiliSearchTimeOutError extends MeiliSearchError {
4+
override name = 'MeiliSearchTimeOutError';
5+
46
constructor(message: string) {
57
super(message);
6-
7-
// Make errors comparison possible. ex: error instanceof MeiliSearchTimeOutError.
8-
Object.setPrototypeOf(this, MeiliSearchTimeOutError.prototype);
9-
10-
this.name = 'MeiliSearchTimeOutError';
11-
12-
if (Error.captureStackTrace) {
13-
Error.captureStackTrace(this, MeiliSearchTimeOutError);
14-
}
158
}
169
}
17-
18-
export { MeiliSearchTimeOutError };

0 commit comments

Comments
 (0)