-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from strapi/feat/http-error-handling
- Loading branch information
Showing
14 changed files
with
314 additions
and
51 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
export class HTTPError extends Error { | ||
public name = 'HTTPError'; | ||
public response: Response; | ||
public request: Request; | ||
|
||
constructor(response: Response, request: Request) { | ||
const code: string = response.status?.toString() ?? ''; | ||
const title = response.statusText ?? ''; | ||
const status = `${code} ${title}`.trim(); | ||
const reason = status ? `status code ${status}` : 'an unknown error'; | ||
|
||
super(`Request failed with ${reason}: ${request.method} ${request.url}`); | ||
|
||
this.response = response; | ||
this.request = request; | ||
} | ||
} | ||
|
||
export class HTTPAuthorizationError extends HTTPError { | ||
public name = 'HTTPAuthorizationError'; | ||
} | ||
|
||
export class HTTPNotFoundError extends HTTPError { | ||
public name = 'HTTPNotFoundError'; | ||
} | ||
|
||
export class HTTPBadRequestError extends HTTPError { | ||
public name = 'HTTPBadRequestError'; | ||
} | ||
|
||
export class HTTPInternalServerError extends HTTPError { | ||
public name = 'HTTPInternalServerError'; | ||
} | ||
|
||
export class HTTPForbiddenError extends HTTPError { | ||
public name = 'HTTPForbiddenError'; | ||
} | ||
|
||
export class HTTPTimeoutError extends HTTPError { | ||
public name = 'HTTPTimeoutError'; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './sdk'; | ||
export * from './url'; | ||
export * from './http'; |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export enum StatusCode { | ||
OK = 200, | ||
CREATED = 201, | ||
NO_CONTENT = 204, | ||
BAD_REQUEST = 400, | ||
UNAUTHORIZED = 401, | ||
FORBIDDEN = 403, | ||
NOT_FOUND = 404, | ||
TIMEOUT = 408, | ||
INTERNAL_SERVER_ERROR = 500, | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from './client'; | ||
export * from './constants'; |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { | ||
HTTPAuthorizationError, | ||
HTTPBadRequestError, | ||
HTTPError, | ||
HTTPForbiddenError, | ||
HTTPInternalServerError, | ||
HTTPNotFoundError, | ||
HTTPTimeoutError, | ||
} from '../../../src/errors'; | ||
import { StatusCode } from '../../../src/http'; | ||
import { mockRequest, mockResponse } from '../mocks'; | ||
|
||
describe('HTTP Errors', () => { | ||
describe('HTTPError', () => { | ||
it('should correctly instantiate with a status code and status text', () => { | ||
// Arrange | ||
const response = mockResponse(504, 'Gateway Timeout'); | ||
const request = mockRequest('GET', 'https://example.com/resource'); | ||
|
||
// Act | ||
const error = new HTTPError(response, request); | ||
|
||
// Assert | ||
expect(error.name).toBe('HTTPError'); | ||
expect(error.message).toBe( | ||
'Request failed with status code 504 Gateway Timeout: GET https://example.com/resource' | ||
); | ||
expect(error.response).toBe(response); | ||
expect(error.request).toBe(request); | ||
}); | ||
|
||
it('should handle status code without status text', () => { | ||
// Arrange | ||
const response = mockResponse(500, ''); | ||
const request = mockRequest('POST', 'https://example.com/update'); | ||
|
||
// Act | ||
const error = new HTTPError(response, request); | ||
|
||
// Assert | ||
expect(error.message).toBe( | ||
'Request failed with status code 500: POST https://example.com/update' | ||
); | ||
}); | ||
|
||
it('should handle requests with no status code', () => { | ||
// Arrange | ||
const response = mockResponse(undefined as any, ''); | ||
const request = mockRequest('GET', 'https://example.com/unknown'); | ||
|
||
// Act | ||
const error = new HTTPError(response, request); | ||
|
||
// Assert | ||
expect(error.message).toBe( | ||
'Request failed with an unknown error: GET https://example.com/unknown' | ||
); | ||
}); | ||
}); | ||
|
||
it.each([ | ||
[HTTPBadRequestError.name, HTTPBadRequestError, StatusCode.BAD_REQUEST], | ||
[HTTPAuthorizationError.name, HTTPAuthorizationError, StatusCode.UNAUTHORIZED], | ||
[HTTPForbiddenError.name, HTTPForbiddenError, StatusCode.FORBIDDEN], | ||
[HTTPNotFoundError.name, HTTPNotFoundError, StatusCode.NOT_FOUND], | ||
[HTTPTimeoutError.name, HTTPTimeoutError, StatusCode.TIMEOUT], | ||
[HTTPInternalServerError.name, HTTPInternalServerError, StatusCode.INTERNAL_SERVER_ERROR], | ||
])('%s', (name, errorClass, status) => { | ||
// Arrange | ||
const response = mockResponse(status, name); | ||
const request = mockRequest('GET', 'https://example.com'); | ||
|
||
// Act | ||
const error = new errorClass(response, request); | ||
|
||
// Assert | ||
expect(error).toBeInstanceOf(HTTPError); | ||
expect(error.name).toBe(name); | ||
expect(error.message).toBe( | ||
`Request failed with status code ${status} ${name}: GET https://example.com` | ||
); | ||
expect(error.response).toBe(response); | ||
expect(error.request).toBe(request); | ||
}); | ||
}); |
File renamed without changes.
File renamed without changes.
Oops, something went wrong.