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 { objectIsEmpty } from '../helpers';
|
||||
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 = ({
|
||||
path,
|
||||
successCallback,
|
||||
|
@ -74,47 +82,51 @@ backendCallProps) => {
|
|||
|
||||
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)
|
||||
.then((response) => {
|
||||
if (response.status === 401) {
|
||||
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) => {
|
||||
if (isSuccessful) {
|
||||
successCallback(result);
|
||||
} else if (is403) {
|
||||
let jsonResult = null;
|
||||
try {
|
||||
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) {
|
||||
onUnauthorized(result);
|
||||
onUnauthorized(jsonResult);
|
||||
} else if (UserService.isPublicUser()) {
|
||||
window.location.href = '/public/sign-out';
|
||||
} else {
|
||||
// Hopefully we can make this service a hook and use the error message context directly
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(result.message);
|
||||
alert(jsonResult.message);
|
||||
}
|
||||
} else if (!result.response.ok) {
|
||||
if (failureCallback) {
|
||||
failureCallback(jsonResult);
|
||||
} else {
|
||||
let message = 'A server error occurred.';
|
||||
if (result.message) {
|
||||
message = result.message;
|
||||
if (jsonResult.message) {
|
||||
message = jsonResult.message;
|
||||
}
|
||||
if (failureCallback) {
|
||||
failureCallback(result);
|
||||
} else {
|
||||
console.error(message);
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(message);
|
||||
}
|
||||
} else {
|
||||
successCallback(jsonResult);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
Loading…
Reference in New Issue