diff --git a/resources/assets/src/js/net.js b/resources/assets/src/js/net.js
index 8af5c37d..2a7c609b 100644
--- a/resources/assets/src/js/net.js
+++ b/resources/assets/src/js/net.js
@@ -3,6 +3,13 @@ import { emit } from './event';
import { queryStringify } from './utils';
import { showAjaxError } from './notify';
+class HTTPError extends Error {
+ constructor(message, response) {
+ super(message);
+ this.response = response;
+ }
+}
+
const empty = Object.create(null);
/** @type Request */
export const init = {
@@ -30,9 +37,8 @@ export async function walkFetch(request) {
? response.json()
: response.text();
} else {
- const text = await response.text();
- emit('fetchError', text);
- showAjaxError(text);
+ const res = response.clone();
+ throw new HTTPError(await response.text(), res);
}
} catch (error) {
emit('fetchError', error);
diff --git a/resources/assets/src/js/notify.js b/resources/assets/src/js/notify.js
index 227556b0..a695f617 100644
--- a/resources/assets/src/js/notify.js
+++ b/resources/assets/src/js/notify.js
@@ -21,16 +21,11 @@ export function showMsg(msg, type = 'info') {
/**
* Show modal if error occured when sending an ajax request.
*
- * @param {TypeError | string} error
+ * @param {Error} error
* @return {void}
*/
export function showAjaxError(error) {
- if (!error) {
- return console.warn('Empty Ajax response body.');
- }
-
- const message = typeof error === 'string' ? error : error.message;
- showModal(message.replace(/\n/g, '
'), trans('general.fatalError'), 'danger');
+ showModal(error.message.replace(/\n/g, '
'), trans('general.fatalError'), 'danger');
}
/**
diff --git a/resources/assets/tests/js/net.test.js b/resources/assets/tests/js/net.test.js
index 63f9ad6c..67fd03ca 100644
--- a/resources/assets/tests/js/net.test.js
+++ b/resources/assets/tests/js/net.test.js
@@ -78,10 +78,11 @@ test('the POST method', async () => {
test('low level fetch', async () => {
const json = jest.fn().mockResolvedValue({});
window.fetch = jest.fn()
- .mockRejectedValueOnce(new Error)
+ .mockRejectedValueOnce(new Error('network'))
.mockResolvedValueOnce({
ok: false,
- text: () => Promise.resolve('404')
+ text: () => Promise.resolve('404'),
+ clone: () => ({})
})
.mockResolvedValueOnce({
ok: true,
@@ -101,11 +102,13 @@ test('low level fetch', async () => {
await net.walkFetch(request);
expect(showAjaxError.mock.calls[0][0]).toBeInstanceOf(Error);
+ expect(showAjaxError.mock.calls[0][0]).toHaveProperty('message', 'network');
expect(stub).toBeCalledWith(expect.any(Error));
await net.walkFetch(request);
- expect(showAjaxError).toBeCalledWith('404');
- expect(stub).toBeCalledWith('404');
+ expect(showAjaxError.mock.calls[1][0]).toBeInstanceOf(Error);
+ expect(stub.mock.calls[1][0]).toHaveProperty('message', '404');
+ expect(stub.mock.calls[1][0]).toHaveProperty('response');
await net.walkFetch(request);
expect(json).toBeCalled();
diff --git a/resources/assets/tests/js/notify.test.js b/resources/assets/tests/js/notify.test.js
index 50d421d0..658d47e7 100644
--- a/resources/assets/tests/js/notify.test.js
+++ b/resources/assets/tests/js/notify.test.js
@@ -12,13 +12,9 @@ test('show message', () => {
});
test('show AJAX error', () => {
- notify.showAjaxError(); // Can be no arguments
-
$.fn.modal = function () {
document.body.innerHTML = this.html();
};
- notify.showAjaxError('error\nerror');
- expect(document.body.innerHTML).toContain('error
error');
notify.showAjaxError(new Error('an-error'));
expect(document.body.innerHTML).toContain('an-error');