-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- New and improved from ent-search - this one automatically sets flash messages for you so you don't have to pass in a callback!
- Loading branch information
Showing
2 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
...ins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts
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,50 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
jest.mock('./', () => ({ | ||
FlashMessagesLogic: { actions: { setFlashMessages: jest.fn() } }, | ||
})); | ||
import { FlashMessagesLogic } from './'; | ||
|
||
import { handleAPIError } from './handle_api_errors'; | ||
|
||
describe('handleAPIError', () => { | ||
const mockHttpError = { | ||
body: { | ||
statusCode: 404, | ||
error: 'Not Found', | ||
message: 'Could not find X,Could not find Y,Something else bad happened', | ||
attributes: { | ||
errors: ['Could not find X', 'Could not find Y', 'Something else bad happened'], | ||
}, | ||
}, | ||
} as any; | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('converts API errors into flash messages', () => { | ||
handleAPIError(mockHttpError); | ||
|
||
expect(FlashMessagesLogic.actions.setFlashMessages).toHaveBeenCalledWith([ | ||
{ type: 'error', message: 'Could not find X' }, | ||
{ type: 'error', message: 'Could not find Y' }, | ||
{ type: 'error', message: 'Something else bad happened' }, | ||
]); | ||
}); | ||
|
||
it('displays a generic error message and re-throws non-API errors', () => { | ||
try { | ||
handleAPIError(Error('whatever') as any); | ||
} catch (e) { | ||
expect(e.message).toEqual('whatever'); | ||
expect(FlashMessagesLogic.actions.setFlashMessages).toHaveBeenCalledWith([ | ||
{ type: 'error', message: 'An unexpected error occurred' }, | ||
]); | ||
} | ||
}); | ||
}); |
46 changes: 46 additions & 0 deletions
46
.../plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts
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,46 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { HttpResponse } from 'src/core/public'; | ||
|
||
import { FlashMessagesLogic, IFlashMessage } from './'; | ||
|
||
/** | ||
* The API errors we are handling can come from one of two ways: | ||
* - When our http calls recieve a response containing an error code, such as a 404 or 500 | ||
* - Our own JS while handling a successful response | ||
* | ||
* In the first case, if it is a purposeful error (like a 404) we will receive an | ||
* `errors` property in the response's data, which will contain messages we can | ||
* display to the user. | ||
*/ | ||
interface IErrorResponse { | ||
statusCode: number; | ||
error: string; | ||
message: string; | ||
attributes: { | ||
errors: string[]; | ||
}; | ||
} | ||
|
||
/** | ||
* Converts API/HTTP errors into user-facing Flash Messages | ||
*/ | ||
export const handleAPIError = (error: HttpResponse<IErrorResponse>) => { | ||
const defaultErrorMessage = 'An unexpected error occurred'; | ||
|
||
const errorFlashMessages: IFlashMessage[] = Array.isArray(error?.body?.attributes?.errors) | ||
? error.body!.attributes.errors.map((message) => ({ type: 'error', message })) | ||
: [{ type: 'error', message: defaultErrorMessage }]; | ||
|
||
FlashMessagesLogic.actions.setFlashMessages(errorFlashMessages); | ||
|
||
// If this was a programming error or a failed request (such as a CORS) error, | ||
// we rethrow the error so it shows up in the developer console | ||
if (!error?.body?.message) { | ||
throw error; | ||
} | ||
}; |