better-fe-error-handling (#1406)
* update error handling in HttpService to handle non-json responses better w/ burnettk * fixed cypress tests --------- Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
6643db9f2f
commit
91e988ff11
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable max-classes-per-file */
|
||||||
import { BACKEND_BASE_URL } from '../config';
|
import { BACKEND_BASE_URL } from '../config';
|
||||||
import { objectIsEmpty } from '../helpers';
|
import { objectIsEmpty } from '../helpers';
|
||||||
import UserService from './UserService';
|
import UserService from './UserService';
|
||||||
|
@ -36,6 +37,13 @@ export class UnauthenticatedError extends Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class UnexpectedResponseError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'UnexpectedResponseError';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const makeCallToBackend = ({
|
const makeCallToBackend = ({
|
||||||
path,
|
path,
|
||||||
successCallback,
|
successCallback,
|
||||||
|
@ -74,47 +82,51 @@ backendCallProps) => {
|
||||||
|
|
||||||
const updatedPath = path.replace(/^\/v1\.0/, '');
|
const updatedPath = path.replace(/^\/v1\.0/, '');
|
||||||
|
|
||||||
let isSuccessful = true;
|
|
||||||
// this fancy 403 handling is like this because we want to get the response body.
|
|
||||||
// otherwise, we would just throw an exception.
|
|
||||||
let is403 = false;
|
|
||||||
fetch(`${BACKEND_BASE_URL}${updatedPath}`, httpArgs)
|
fetch(`${BACKEND_BASE_URL}${updatedPath}`, httpArgs)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
throw new UnauthenticatedError('You must be authenticated to do this.');
|
throw new UnauthenticatedError('You must be authenticated to do this.');
|
||||||
} else if (response.status === 403) {
|
|
||||||
is403 = true;
|
|
||||||
isSuccessful = false;
|
|
||||||
} else if (!response.ok) {
|
|
||||||
isSuccessful = false;
|
|
||||||
}
|
}
|
||||||
return response.json();
|
return response.text().then((result: any) => {
|
||||||
|
return { response, text: result };
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
if (isSuccessful) {
|
let jsonResult = null;
|
||||||
successCallback(result);
|
try {
|
||||||
} else if (is403) {
|
jsonResult = JSON.parse(result.text);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
throw new UnexpectedResponseError(
|
||||||
|
`Received unexpected response from server. Status: ${result.response.status}: ${result.response.statusText}. Body: ${result.text}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
if (result.response.status === 403) {
|
||||||
if (onUnauthorized) {
|
if (onUnauthorized) {
|
||||||
onUnauthorized(result);
|
onUnauthorized(jsonResult);
|
||||||
} else if (UserService.isPublicUser()) {
|
} else if (UserService.isPublicUser()) {
|
||||||
window.location.href = '/public/sign-out';
|
window.location.href = '/public/sign-out';
|
||||||
} else {
|
} else {
|
||||||
// Hopefully we can make this service a hook and use the error message context directly
|
// Hopefully we can make this service a hook and use the error message context directly
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
alert(result.message);
|
alert(jsonResult.message);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let message = 'A server error occurred.';
|
|
||||||
if (result.message) {
|
|
||||||
message = result.message;
|
|
||||||
}
|
}
|
||||||
|
} else if (!result.response.ok) {
|
||||||
if (failureCallback) {
|
if (failureCallback) {
|
||||||
failureCallback(result);
|
failureCallback(jsonResult);
|
||||||
} else {
|
} else {
|
||||||
|
let message = 'A server error occurred.';
|
||||||
|
if (jsonResult.message) {
|
||||||
|
message = jsonResult.message;
|
||||||
|
}
|
||||||
console.error(message);
|
console.error(message);
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
alert(message);
|
alert(message);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
successCallback(jsonResult);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|
Loading…
Reference in New Issue