Change failure behaviour

This commit is contained in:
rubikscraft
2022-07-04 17:11:42 +02:00
parent ba47d0bff4
commit c8722d8944
30 changed files with 320 additions and 174 deletions

View File

@@ -17,6 +17,7 @@ const ApiErrorResponse = ApiResponseBase.merge(
z.object({
success: z.literal(false),
data: z.object({
type: z.string(),
message: z.string(),
}),
}),

View File

@@ -3,20 +3,108 @@
// Since now they dont just come out of nowhere
// -> Side effects go brrr
// Failuretype
export enum FT {
Unknown = 'unknown',
Database = 'database',
SysValidation = 'sysvalidation',
UsrValidation = 'usrvalidation',
Permission = 'permission',
NotFound = 'notFound',
Conflict = 'conflict',
Internal = 'internal',
Authentication = 'authentication',
Impossible = 'impossible',
Network = 'network',
}
interface FTProp {
important: boolean;
code: number;
}
const FTProps: {
[key in FT]: FTProp;
} = {
[FT.Unknown]: {
important: false,
code: 500,
},
[FT.Internal]: {
important: true,
code: 500,
},
[FT.Database]: {
important: true,
code: 500,
},
[FT.Network]: {
important: true,
code: 500,
},
[FT.SysValidation]: {
important: true,
code: 500,
},
[FT.UsrValidation]: {
important: false,
code: 400,
},
[FT.Permission]: {
important: false,
code: 403,
},
[FT.NotFound]: {
important: false,
code: 404,
},
[FT.Conflict]: {
important: false,
code: 409,
},
[FT.Authentication]: {
important: false,
code: 200,
} ,
[FT.Impossible]: {
important: true,
code: 422,
} ,
};
export class Failure {
private __68351953531423479708__id_failure = 1148363914;
constructor(
private readonly reason?: string,
private readonly stack?: string,
private readonly type: FT = FT.Unknown,
) {}
getReason(): string {
return this.reason ?? 'Unknown';
}
getStack(): string {
return this.stack ?? 'None';
getStack(): string | undefined {
return this.stack;
}
getType(): FT {
return this.type;
}
getName(): string {
const capitalizedType =
this.type.charAt(0).toUpperCase() + this.type.slice(1);
return `${capitalizedType}Failure`;
}
getCode(): number {
return FTProps[this.type].code;
}
isImportant() {
return FTProps[this.type].important;
}
static deserialize(data: any): Failure {
@@ -24,22 +112,26 @@ export class Failure {
throw new Error('Invalid failure data');
}
return new Failure(data.reason, data.stack);
return new Failure(data.reason, data.stack, data.type);
}
}
export function Fail(reason?: any): Failure {
export function Fail(type: FT, reason: any): Failure {
if (typeof reason === 'string') {
return new Failure(reason);
return new Failure(reason, undefined, type);
} else if (reason instanceof Error) {
return new Failure(reason.message, reason.stack);
return new Failure(reason.message, reason.stack, type);
} else if (reason instanceof Failure) {
return reason;
throw new Error('Cannot fail with a failure, just return it');
} else {
return new Failure('Converted(' + reason + ')');
return new Failure('Unkown reason', undefined, type);
}
}
export function IsFailure(value: any): value is Failure {
return value.__68351953531423479708__id_failure === 1148363914;
}
export type Failable<T> = T | Failure;
export type AsyncFailable<T> = Promise<Failable<T>>;

View File

@@ -4,7 +4,7 @@ import {
SupportedImageMimes,
SupportedMimeCategory
} from '../dto/mimes.dto';
import { Fail, Failable } from '../types';
import { Fail, Failable, FT } from '../types';
export function ParseMime(mime: string): Failable<FullMime> {
if (SupportedImageMimes.includes(mime))
@@ -13,5 +13,5 @@ export function ParseMime(mime: string): Failable<FullMime> {
if (SupportedAnimMimes.includes(mime))
return { mime, type: SupportedMimeCategory.Animation };
return Fail('Unsupported mime type');
return Fail(FT.Validation, 'Unsupported mime type');
}