1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-03-23 00:16:25 +01:00

feat: make maintenance-related 503s more intuitive (#5018)

This makes maintenance-related 503s more intuitive on our UI by
mentioning that maintenance banner is currently enabled.


![image](https://github.com/Unleash/unleash/assets/14320932/43142c58-6b87-4b2d-9239-50f2bb1409e6)
This commit is contained in:
Nuno Góis 2023-10-16 09:27:29 +01:00 committed by GitHub
parent c41f23ae54
commit 6c21ed5f74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 7 deletions

View File

@ -4,3 +4,4 @@ export const CREATED = 201;
export const NOT_FOUND = 404;
export const FORBIDDEN = 403;
export const UNAUTHORIZED = 401;
export const UNAVAILABLE = 503;

View File

@ -5,6 +5,7 @@ import {
NOT_FOUND,
OK,
UNAUTHORIZED,
UNAVAILABLE,
} from 'constants/statusCodes';
import {
AuthenticationError,
@ -12,6 +13,7 @@ import {
ForbiddenError,
headers,
NotFoundError,
UnavailableError,
} from 'utils/apiUtils';
import { formatApiPath } from 'utils/formatPath';
import { ACCESS_DENIED_TEXT } from 'utils/formatAccessText';
@ -27,6 +29,7 @@ interface IUseAPI {
handleNotFound?: ApiErrorHandler;
handleUnauthorized?: ApiErrorHandler;
handleForbidden?: ApiErrorHandler;
handleUnavailable?: ApiErrorHandler;
propagateErrors?: boolean;
}
@ -35,6 +38,7 @@ const useAPI = ({
handleNotFound,
handleForbidden,
handleUnauthorized,
handleUnavailable,
propagateErrors = false,
}: IUseAPI) => {
const [errors, setErrors] = useState<Record<string, string>>({});
@ -104,6 +108,22 @@ const useAPI = ({
}
}
if (res.status === UNAVAILABLE) {
if (handleUnavailable) {
return handleUnavailable(setErrors, res, requestId);
} else {
setErrors((prev) => ({
...prev,
unavailable: 'This operation is unavailable',
}));
}
if (propagateErrors) {
const response = await res.json();
throw new UnavailableError(res.status, response);
}
}
if (res.status > 399) {
const response = await res.json();
if (response?.details?.length > 0 && propagateErrors) {

View File

@ -3,12 +3,17 @@ import {
FORBIDDEN,
NOT_FOUND,
UNAUTHORIZED,
UNAVAILABLE,
} from 'constants/statusCodes';
export interface IErrorBody {
message?: string;
details?: { message: string }[];
}
const getErrorMessage = (body: IErrorBody) =>
body.details?.[0]?.message || body.message;
export class AuthenticationError extends Error {
statusCode: number;
@ -24,23 +29,31 @@ export class ForbiddenError extends Error {
body: IErrorBody;
constructor(statusCode: number = FORBIDDEN, body: IErrorBody = {}) {
super(
body.details?.length
? body.details[0].message
: 'You cannot perform this action',
);
super(getErrorMessage(body) || 'You cannot perform this action');
this.name = 'ForbiddenError';
this.statusCode = statusCode;
this.body = body;
}
}
export class UnavailableError extends Error {
statusCode: number;
body: IErrorBody;
constructor(statusCode: number = UNAVAILABLE, body: IErrorBody = {}) {
super(getErrorMessage(body) || 'This operation is unavailable');
this.name = 'UnavailableError';
this.statusCode = statusCode;
this.body = body;
}
}
export class BadRequestError extends Error {
statusCode: number;
body: IErrorBody;
constructor(statusCode: number = BAD_REQUEST, body: IErrorBody = {}) {
super(body.details?.length ? body.details[0].message : 'Bad request');
super(getErrorMessage(body) || 'Bad request');
this.name = 'BadRequestError';
this.statusCode = statusCode;
this.body = body;

View File

@ -2,6 +2,9 @@ import { IUnleashConfig } from '../types';
import MaintenanceService from '../services/maintenance-service';
import { IAuthRequest } from '../routes/unleash-types';
export const MAINTENANCE_MODE_ENABLED =
'Unleash is currently in maintenance mode.';
const maintenanceMiddleware = (
{ getLogger }: Pick<IUnleashConfig, 'getLogger' | 'flagResolver'>,
maintenanceService: MaintenanceService,
@ -17,7 +20,9 @@ const maintenanceMiddleware = (
writeMethod &&
(await maintenanceService.isMaintenanceMode())
) {
res.status(503).send({});
res.status(503).send({
message: MAINTENANCE_MODE_ENABLED,
});
} else {
next();
}