Always throw an Error instance

This commit is contained in:
Pig Fang 2018-09-11 23:29:02 +08:00
parent 205a8f54f0
commit 6bfe30b394
4 changed files with 18 additions and 18 deletions

View File

@ -3,6 +3,13 @@ import { emit } from './event';
import { queryStringify } from './utils'; import { queryStringify } from './utils';
import { showAjaxError } from './notify'; import { showAjaxError } from './notify';
class HTTPError extends Error {
constructor(message, response) {
super(message);
this.response = response;
}
}
const empty = Object.create(null); const empty = Object.create(null);
/** @type Request */ /** @type Request */
export const init = { export const init = {
@ -30,9 +37,8 @@ export async function walkFetch(request) {
? response.json() ? response.json()
: response.text(); : response.text();
} else { } else {
const text = await response.text(); const res = response.clone();
emit('fetchError', text); throw new HTTPError(await response.text(), res);
showAjaxError(text);
} }
} catch (error) { } catch (error) {
emit('fetchError', error); emit('fetchError', error);

View File

@ -21,16 +21,11 @@ export function showMsg(msg, type = 'info') {
/** /**
* Show modal if error occured when sending an ajax request. * Show modal if error occured when sending an ajax request.
* *
* @param {TypeError | string} error * @param {Error} error
* @return {void} * @return {void}
*/ */
export function showAjaxError(error) { export function showAjaxError(error) {
if (!error) { showModal(error.message.replace(/\n/g, '<br>'), trans('general.fatalError'), 'danger');
return console.warn('Empty Ajax response body.');
}
const message = typeof error === 'string' ? error : error.message;
showModal(message.replace(/\n/g, '<br>'), trans('general.fatalError'), 'danger');
} }
/** /**

View File

@ -78,10 +78,11 @@ test('the POST method', async () => {
test('low level fetch', async () => { test('low level fetch', async () => {
const json = jest.fn().mockResolvedValue({}); const json = jest.fn().mockResolvedValue({});
window.fetch = jest.fn() window.fetch = jest.fn()
.mockRejectedValueOnce(new Error) .mockRejectedValueOnce(new Error('network'))
.mockResolvedValueOnce({ .mockResolvedValueOnce({
ok: false, ok: false,
text: () => Promise.resolve('404') text: () => Promise.resolve('404'),
clone: () => ({})
}) })
.mockResolvedValueOnce({ .mockResolvedValueOnce({
ok: true, ok: true,
@ -101,11 +102,13 @@ test('low level fetch', async () => {
await net.walkFetch(request); await net.walkFetch(request);
expect(showAjaxError.mock.calls[0][0]).toBeInstanceOf(Error); expect(showAjaxError.mock.calls[0][0]).toBeInstanceOf(Error);
expect(showAjaxError.mock.calls[0][0]).toHaveProperty('message', 'network');
expect(stub).toBeCalledWith(expect.any(Error)); expect(stub).toBeCalledWith(expect.any(Error));
await net.walkFetch(request); await net.walkFetch(request);
expect(showAjaxError).toBeCalledWith('404'); expect(showAjaxError.mock.calls[1][0]).toBeInstanceOf(Error);
expect(stub).toBeCalledWith('404'); expect(stub.mock.calls[1][0]).toHaveProperty('message', '404');
expect(stub.mock.calls[1][0]).toHaveProperty('response');
await net.walkFetch(request); await net.walkFetch(request);
expect(json).toBeCalled(); expect(json).toBeCalled();

View File

@ -12,13 +12,9 @@ test('show message', () => {
}); });
test('show AJAX error', () => { test('show AJAX error', () => {
notify.showAjaxError(); // Can be no arguments
$.fn.modal = function () { $.fn.modal = function () {
document.body.innerHTML = this.html(); document.body.innerHTML = this.html();
}; };
notify.showAjaxError('error\nerror');
expect(document.body.innerHTML).toContain('error<br>error');
notify.showAjaxError(new Error('an-error')); notify.showAjaxError(new Error('an-error'));
expect(document.body.innerHTML).toContain('an-error'); expect(document.body.innerHTML).toContain('an-error');