Partly refactor errors
This commit is contained in:
parent
c8722d8944
commit
d507fcfaf0
|
@ -113,7 +113,8 @@ export class SysPreferenceService {
|
|||
): AsyncFailable<PrefValueType> {
|
||||
let pref = await this.getPreference(key);
|
||||
if (HasFailed(pref)) return pref;
|
||||
if (pref.type !== type) return Fail(FT.UsrValidation, 'Invalid preference type');
|
||||
if (pref.type !== type)
|
||||
return Fail(FT.UsrValidation, 'Invalid preference type');
|
||||
|
||||
return pref.value;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import {
|
||||
ArgumentMetadata,
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
PipeTransform,
|
||||
ArgumentMetadata, Injectable,
|
||||
PipeTransform
|
||||
} from '@nestjs/common';
|
||||
import { Ext2Mime } from 'picsur-shared/dist/dto/mimes.dto';
|
||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
||||
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
||||
import { ImageFullId } from '../../models/constants/image-full-id.const';
|
||||
|
||||
|
@ -15,23 +14,23 @@ export class ImageFullIdPipe implements PipeTransform<string, ImageFullId> {
|
|||
if (split.length === 2) {
|
||||
const [id, ext] = split;
|
||||
if (!UUIDRegex.test(id))
|
||||
throw new BadRequestException('Invalid image identifier');
|
||||
throw Fail(FT.UsrValidation, 'Invalid image identifier');
|
||||
|
||||
const mime = Ext2Mime(ext);
|
||||
|
||||
if (mime === undefined)
|
||||
throw new BadRequestException('Invalid image identifier');
|
||||
throw Fail(FT.UsrValidation, 'Invalid image identifier');
|
||||
|
||||
return { type: 'normal', id, ext, mime };
|
||||
} else if (split.length === 1) {
|
||||
const [id] = split;
|
||||
|
||||
if (!UUIDRegex.test(id))
|
||||
throw new BadRequestException('Invalid image identifier');
|
||||
throw Fail(FT.UsrValidation, 'Invalid image identifier');
|
||||
|
||||
return { type: 'original', id, ext: null, mime: null };
|
||||
} else {
|
||||
throw new BadRequestException('Invalid image identifier');
|
||||
throw Fail(FT.UsrValidation, 'Invalid image identifier');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import {
|
||||
ArgumentMetadata,
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
PipeTransform,
|
||||
ArgumentMetadata, Injectable,
|
||||
PipeTransform
|
||||
} from '@nestjs/common';
|
||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
||||
import { UUIDRegex } from 'picsur-shared/dist/util/common-regex';
|
||||
|
||||
@Injectable()
|
||||
export class ImageIdPipe implements PipeTransform<string, string> {
|
||||
transform(value: string, metadata: ArgumentMetadata): string {
|
||||
if (UUIDRegex.test(value)) return value;
|
||||
throw new BadRequestException('Invalid image id');
|
||||
throw Fail(FT.UsrValidation, 'Invalid image id');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import { MultipartFields, MultipartFile } from '@fastify/multipart';
|
||||
import {
|
||||
ArgumentMetadata,
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
InternalServerErrorException,
|
||||
ArgumentMetadata, Injectable,
|
||||
Logger,
|
||||
PipeTransform,
|
||||
Scope
|
||||
} from '@nestjs/common';
|
||||
import { FastifyRequest } from 'fastify';
|
||||
import { HasFailed } from 'picsur-shared/dist/types';
|
||||
import { Fail, FT, HasFailed } from 'picsur-shared/dist/types';
|
||||
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
||||
import { MultipartConfigService } from '../../config/early/multipart.config.service';
|
||||
import {
|
||||
|
@ -32,11 +29,11 @@ export class MultiPartPipe implements PipeTransform {
|
|||
let zodSchema = (metadata?.metatype as ZodDtoStatic)?.zodSchema;
|
||||
if (!zodSchema) {
|
||||
this.logger.error('Invalid scheme on multipart body');
|
||||
throw new InternalServerErrorException('Invalid scheme on backend');
|
||||
throw Fail(FT.Internal, 'Invalid scheme on backend');
|
||||
}
|
||||
|
||||
let multipartData = {};
|
||||
if (!req.isMultipart()) throw new BadRequestException('Invalid file');
|
||||
if (!req.isMultipart()) throw Fail(FT.UsrValidation, 'Invalid file');
|
||||
|
||||
// Fetch all fields from the request
|
||||
let fields: MultipartFields | null = null;
|
||||
|
@ -49,7 +46,7 @@ export class MultiPartPipe implements PipeTransform {
|
|||
} catch (e) {
|
||||
this.logger.warn(e);
|
||||
}
|
||||
if (!fields) throw new BadRequestException('Invalid file');
|
||||
if (!fields) throw Fail(FT.UsrValidation, 'Invalid file');
|
||||
|
||||
// Loop over every formfield that was sent
|
||||
for (const key of Object.keys(fields)) {
|
||||
|
@ -66,10 +63,7 @@ export class MultiPartPipe implements PipeTransform {
|
|||
);
|
||||
} else {
|
||||
const file = await CreateMultiPartFileDto(fields[key] as MultipartFile);
|
||||
if (HasFailed(file)) {
|
||||
this.logger.error(file.getReason());
|
||||
throw new InternalServerErrorException('Invalid file');
|
||||
}
|
||||
if (HasFailed(file)) throw file;
|
||||
(multipartData as any)[key] = file;
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +72,7 @@ export class MultiPartPipe implements PipeTransform {
|
|||
const result = zodSchema.safeParse(multipartData);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
throw new BadRequestException('Invalid file');
|
||||
throw Fail(FT.UsrValidation, 'Invalid file');
|
||||
}
|
||||
|
||||
return result.data;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Multipart } from '@fastify/multipart';
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
Logger,
|
||||
PipeTransform,
|
||||
Scope
|
||||
} from '@nestjs/common';
|
||||
import { FastifyRequest } from 'fastify';
|
||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
||||
import { MultipartConfigService } from '../../config/early/multipart.config.service';
|
||||
|
||||
@Injectable({ scope: Scope.REQUEST })
|
||||
|
@ -18,7 +18,7 @@ export class PostFilePipe implements PipeTransform {
|
|||
) {}
|
||||
|
||||
async transform({ req }: { req: FastifyRequest }) {
|
||||
if (!req.isMultipart()) throw new BadRequestException('Invalid file');
|
||||
if (!req.isMultipart()) throw Fail(FT.UsrValidation, 'Invalid file');
|
||||
|
||||
// Only one file is allowed
|
||||
const file = await req.file({
|
||||
|
@ -27,7 +27,7 @@ export class PostFilePipe implements PipeTransform {
|
|||
files: 1,
|
||||
},
|
||||
});
|
||||
if (file === undefined) throw new BadRequestException('Invalid file');
|
||||
if (file === undefined) throw Fail(FT.UsrValidation, 'Invalid file');
|
||||
|
||||
// Remove empty fields
|
||||
const allFields: Multipart[] = Object.values(file.fields).filter(
|
||||
|
@ -37,14 +37,14 @@ export class PostFilePipe implements PipeTransform {
|
|||
// Remove non-file fields
|
||||
const files = allFields.filter((entry) => entry.file !== undefined);
|
||||
|
||||
if (files.length !== 1) throw new BadRequestException('Invalid file');
|
||||
if (files.length !== 1) throw Fail(FT.UsrValidation, 'Invalid file');
|
||||
|
||||
// Return a buffer of the file
|
||||
try {
|
||||
return await files[0].toBuffer();
|
||||
} catch (e) {
|
||||
this.logger.warn(e);
|
||||
throw new BadRequestException('Invalid file');
|
||||
throw Fail(FT.Internal, 'Invalid file');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,23 +25,27 @@ export class MainExceptionFilter implements ExceptionFilter {
|
|||
return;
|
||||
}
|
||||
|
||||
const status = exception.getCode();
|
||||
const type = exception.getType();
|
||||
|
||||
const message = exception.getReason();
|
||||
const logmessage =
|
||||
message +
|
||||
(exception.getDebugMessage() ? ' - ' + exception.getDebugMessage() : '');
|
||||
|
||||
if (exception.isImportant()) {
|
||||
MainExceptionFilter.logger.error(
|
||||
`${traceString} ${exception.getName()}: ${exception.getReason()}`,
|
||||
`${traceString} ${exception.getName()}: ${logmessage}`,
|
||||
);
|
||||
if (exception.getStack()) {
|
||||
MainExceptionFilter.logger.debug(exception.getStack());
|
||||
}
|
||||
} else {
|
||||
MainExceptionFilter.logger.warn(
|
||||
`${traceString} ${exception.getName()}: ${exception.getReason()}`,
|
||||
`${traceString} ${exception.getName()}: ${logmessage}`,
|
||||
);
|
||||
}
|
||||
|
||||
const status = exception.getCode();
|
||||
const type = exception.getType();
|
||||
const message = exception.getReason();
|
||||
|
||||
const toSend: ApiErrorResponse = {
|
||||
success: false,
|
||||
statusCode: status,
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import {
|
||||
CallHandler,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
InternalServerErrorException,
|
||||
Logger,
|
||||
Injectable, Logger,
|
||||
NestInterceptor,
|
||||
Optional
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { ApiAnySuccessResponse } from 'picsur-shared/dist/dto/api/api.dto';
|
||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
||||
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
||||
import { map, Observable } from 'rxjs';
|
||||
|
||||
|
@ -55,24 +54,24 @@ export class SuccessInterceptor<T> implements NestInterceptor {
|
|||
);
|
||||
|
||||
if (!schemaStatic) {
|
||||
this.logger.warn(
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
"Couldn't find schema",
|
||||
`No zodSchema found on handler ${context.getHandler().name}`,
|
||||
);
|
||||
throw new InternalServerErrorException("Couldn't find schema");
|
||||
}
|
||||
|
||||
let schema = schemaStatic.zodSchema;
|
||||
|
||||
const parseResult = schema.safeParse(data);
|
||||
if (!parseResult.success) {
|
||||
this.logger.warn(
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
'Server produced invalid response',
|
||||
`Function ${context.getHandler().name} failed validation: ${
|
||||
parseResult.error
|
||||
}`,
|
||||
);
|
||||
throw new InternalServerErrorException(
|
||||
'Server produced invalid response',
|
||||
);
|
||||
}
|
||||
|
||||
return parseResult.data;
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
import {
|
||||
ArgumentMetadata,
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
Optional,
|
||||
PipeTransform,
|
||||
PipeTransform
|
||||
} from '@nestjs/common';
|
||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
||||
import { ZodDtoStatic } from 'picsur-shared/dist/util/create-zod-dto';
|
||||
|
||||
export interface ZodValidationPipeOptions {
|
||||
|
@ -36,7 +36,11 @@ export class ZodValidationPipe implements PipeTransform {
|
|||
const parseResult = zodSchema.safeParse(value);
|
||||
|
||||
if (!parseResult.success) {
|
||||
throw new BadRequestException();
|
||||
throw Fail(
|
||||
FT.UsrValidation,
|
||||
'Invalid data',
|
||||
parseResult.error
|
||||
);
|
||||
}
|
||||
|
||||
return parseResult.data;
|
||||
|
|
|
@ -19,13 +19,13 @@ export class AuthManagerService {
|
|||
// in case of any failures
|
||||
const result = JwtDataSchema.safeParse(jwtData);
|
||||
if (!result.success) {
|
||||
return Fail(FT.SysValidation, 'Invalid JWT: ' + result.error);
|
||||
return Fail(FT.SysValidation, undefined, 'Invalid JWT: ' + result.error);
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.jwtService.signAsync(result.data);
|
||||
} catch (e) {
|
||||
return Fail(FT.Internal, "Couldn't create JWT: " + e);
|
||||
return Fail(FT.Internal, undefined, "Couldn't create JWT: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Strategy } from 'passport-local';
|
||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||
|
@ -15,9 +15,7 @@ export class LocalAuthStrategy extends PassportStrategy(Strategy, 'local') {
|
|||
async validate(username: string, password: string): AsyncFailable<EUser> {
|
||||
// All this does is call the usersservice authenticate for authentication
|
||||
const user = await this.usersService.authenticate(username, password);
|
||||
if (HasFailed(user)) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
if (HasFailed(user)) throw user;
|
||||
|
||||
return EUserBackend2EUser(user);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import {
|
||||
ExecutionContext, Injectable,
|
||||
InternalServerErrorException,
|
||||
Logger
|
||||
} from '@nestjs/common';
|
||||
import { ExecutionContext, Injectable, Logger } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { EUser, EUserSchema } from 'picsur-shared/dist/entities/user.entity';
|
||||
|
@ -30,34 +26,42 @@ export class MainAuthGuard extends AuthGuard(['jwt', 'guest']) {
|
|||
// Sanity check
|
||||
const result = await super.canActivate(context);
|
||||
if (result !== true) {
|
||||
this.logger.error('Main Auth has denied access, this should not happen');
|
||||
throw new InternalServerErrorException();
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
'Main Auth has denied access, this should not happen',
|
||||
);
|
||||
}
|
||||
|
||||
const user = await this.validateUser(
|
||||
context.switchToHttp().getRequest().user,
|
||||
);
|
||||
if (!user.id) {
|
||||
this.logger.error('User has no id, this should not happen');
|
||||
throw new InternalServerErrorException();
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
'User has no id, this should not happen',
|
||||
);
|
||||
}
|
||||
|
||||
// These are the permissions required to access the route
|
||||
const permissions = this.extractPermissions(context);
|
||||
if (HasFailed(permissions)) {
|
||||
this.logger.error(
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
'Fetching route permission failed: ' + permissions.getReason(),
|
||||
);
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
// These are the permissions the user has
|
||||
const userPermissions = await this.usersService.getPermissions(user.id);
|
||||
if (HasFailed(userPermissions)) {
|
||||
this.logger.warn(
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
'Fetching user permissions failed: ' + userPermissions.getReason(),
|
||||
);
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
context.switchToHttp().getRequest().userPermissions = userPermissions;
|
||||
|
@ -78,12 +82,14 @@ export class MainAuthGuard extends AuthGuard(['jwt', 'guest']) {
|
|||
if (permissions === undefined)
|
||||
return Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
`${handlerName} does not have any permissions defined, denying access`,
|
||||
);
|
||||
|
||||
if (!isPermissionsArray(permissions))
|
||||
return Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
`Permissions for ${handlerName} is not a string array`,
|
||||
);
|
||||
|
||||
|
@ -93,10 +99,11 @@ export class MainAuthGuard extends AuthGuard(['jwt', 'guest']) {
|
|||
private async validateUser(user: EUser): Promise<EUser> {
|
||||
const result = EUserSchema.safeParse(user);
|
||||
if (!result.success) {
|
||||
this.logger.warn(
|
||||
throw Fail(
|
||||
FT.Internal,
|
||||
undefined,
|
||||
`Invalid user object, where it should always be valid: ${result.error}`,
|
||||
);
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
return result.data;
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { Controller, Get, Request } from '@nestjs/common';
|
||||
import { UserInfoResponse } from 'picsur-shared/dist/dto/api/user-manage.dto';
|
||||
import { Permission } from 'picsur-shared/dist/dto/permissions.enum';
|
||||
import { RequiredPermissions } from '../../../decorators/permissions.decorator';
|
||||
import { Fail, FT } from 'picsur-shared/dist/types';
|
||||
import { NoPermissions, RequiredPermissions } from '../../../decorators/permissions.decorator';
|
||||
import { ReqUserID } from '../../../decorators/request-user.decorator';
|
||||
import { Returns } from '../../../decorators/returns.decorator';
|
||||
import type AuthFasityRequest from '../../../models/interfaces/authrequest.dto';
|
||||
|
||||
@Controller('api/experiment')
|
||||
//@NoPermissions()
|
||||
@NoPermissions()
|
||||
@RequiredPermissions(Permission.Settings)
|
||||
export class ExperimentController {
|
||||
@Get()
|
||||
|
@ -16,6 +17,7 @@ export class ExperimentController {
|
|||
@Request() req: AuthFasityRequest,
|
||||
@ReqUserID() thing: string,
|
||||
): Promise<UserInfoResponse> {
|
||||
throw Fail(FT.NotFound, new Error("hello"));
|
||||
return req.user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,8 +58,11 @@ export class ApiService {
|
|||
|
||||
const validateResult = sendSchema.safeParse(data);
|
||||
if (!validateResult.success) {
|
||||
this.logger.error(validateResult.error);
|
||||
return Fail(FT.SysValidation, 'Something went wrong');
|
||||
return Fail(
|
||||
FT.SysValidation,
|
||||
'Something went wrong',
|
||||
validateResult.error,
|
||||
);
|
||||
}
|
||||
|
||||
return this.fetchSafeJson(receiveType, url, {
|
||||
|
@ -92,8 +95,11 @@ export class ApiService {
|
|||
|
||||
const validateResult = resultSchema.safeParse(result);
|
||||
if (!validateResult.success) {
|
||||
this.logger.error(validateResult.error);
|
||||
return Fail(FT.SysValidation, 'Something went wrong');
|
||||
return Fail(
|
||||
FT.SysValidation,
|
||||
'Something went wrong',
|
||||
validateResult.error,
|
||||
);
|
||||
}
|
||||
|
||||
if (validateResult.data.success === false)
|
||||
|
@ -113,8 +119,7 @@ export class ApiService {
|
|||
try {
|
||||
return await response.json();
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
return Fail(FT.Internal, 'Something went wrong');
|
||||
return Fail(FT.Internal, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,8 +155,7 @@ export class ApiService {
|
|||
name,
|
||||
};
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
return Fail(FT.Internal, 'Something went wrong');
|
||||
return Fail(FT.Internal, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +191,7 @@ export class ApiService {
|
|||
error: e,
|
||||
url,
|
||||
});
|
||||
return Fail(FT.Network, 'Network Error');
|
||||
return Fail(FT.Network, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ export enum FT {
|
|||
SysValidation = 'sysvalidation',
|
||||
UsrValidation = 'usrvalidation',
|
||||
Permission = 'permission',
|
||||
NotFound = 'notFound',
|
||||
NotFound = 'notfound',
|
||||
Conflict = 'conflict',
|
||||
Internal = 'internal',
|
||||
Authentication = 'authentication',
|
||||
|
@ -21,6 +21,7 @@ export enum FT {
|
|||
interface FTProp {
|
||||
important: boolean;
|
||||
code: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
const FTProps: {
|
||||
|
@ -29,56 +30,68 @@ const FTProps: {
|
|||
[FT.Unknown]: {
|
||||
important: false,
|
||||
code: 500,
|
||||
message: 'An unkown error occurred',
|
||||
},
|
||||
[FT.Internal]: {
|
||||
important: true,
|
||||
code: 500,
|
||||
message: 'An internal error occurred',
|
||||
},
|
||||
[FT.Database]: {
|
||||
important: true,
|
||||
code: 500,
|
||||
message: 'A database error occurred',
|
||||
},
|
||||
[FT.Network]: {
|
||||
important: true,
|
||||
code: 500,
|
||||
message: 'A network error occurred',
|
||||
},
|
||||
[FT.SysValidation]: {
|
||||
important: true,
|
||||
code: 500,
|
||||
message: 'Validation of internal items failed',
|
||||
},
|
||||
[FT.UsrValidation]: {
|
||||
important: false,
|
||||
code: 400,
|
||||
message: 'Validation of user input failed',
|
||||
},
|
||||
[FT.Permission]: {
|
||||
important: false,
|
||||
code: 403,
|
||||
message: 'Permission denied',
|
||||
},
|
||||
[FT.NotFound]: {
|
||||
important: false,
|
||||
code: 404,
|
||||
message: 'Item(s) could not be found',
|
||||
},
|
||||
[FT.Conflict]: {
|
||||
important: false,
|
||||
code: 409,
|
||||
message: 'There was a conflict',
|
||||
},
|
||||
[FT.Authentication]: {
|
||||
important: false,
|
||||
code: 200,
|
||||
} ,
|
||||
message: 'Authentication failed',
|
||||
},
|
||||
[FT.Impossible]: {
|
||||
important: true,
|
||||
code: 422,
|
||||
} ,
|
||||
message: 'What you are doing is impossible',
|
||||
},
|
||||
};
|
||||
|
||||
export class Failure {
|
||||
private __68351953531423479708__id_failure = 1148363914;
|
||||
|
||||
constructor(
|
||||
private readonly type: FT = FT.Unknown,
|
||||
private readonly reason?: string,
|
||||
private readonly stack?: string,
|
||||
private readonly type: FT = FT.Unknown,
|
||||
private readonly debugMessage?: string,
|
||||
) {}
|
||||
|
||||
getReason(): string {
|
||||
|
@ -89,6 +102,10 @@ export class Failure {
|
|||
return this.stack;
|
||||
}
|
||||
|
||||
getDebugMessage(): string | undefined {
|
||||
return this.debugMessage;
|
||||
}
|
||||
|
||||
getType(): FT {
|
||||
return this.type;
|
||||
}
|
||||
|
@ -112,19 +129,34 @@ export class Failure {
|
|||
throw new Error('Invalid failure data');
|
||||
}
|
||||
|
||||
return new Failure(data.reason, data.stack, data.type);
|
||||
return new Failure(data.type, data.reason, data.stack, data.debugMessage);
|
||||
}
|
||||
}
|
||||
|
||||
export function Fail(type: FT, reason: any): Failure {
|
||||
if (typeof reason === 'string') {
|
||||
return new Failure(reason, undefined, type);
|
||||
} else if (reason instanceof Error) {
|
||||
return new Failure(reason.message, reason.stack, type);
|
||||
} else if (reason instanceof Failure) {
|
||||
export function Fail(type: FT, reason?: any, dbgReason?: any): Failure {
|
||||
const strReason = reason.toString();
|
||||
|
||||
if (typeof dbgReason === 'string') {
|
||||
return new Failure(type, strReason, undefined, dbgReason);
|
||||
} else if (dbgReason instanceof Error) {
|
||||
return new Failure(type, strReason, dbgReason.stack, dbgReason.message);
|
||||
} else if (dbgReason instanceof Failure) {
|
||||
throw new Error('Cannot fail with a failure, just return it');
|
||||
} else {
|
||||
return new Failure('Unkown reason', undefined, type);
|
||||
if (typeof reason === 'string') {
|
||||
return new Failure(type, strReason, undefined, undefined);
|
||||
} else if (reason instanceof Error) {
|
||||
return new Failure(
|
||||
type,
|
||||
FTProps[type].message,
|
||||
reason.stack,
|
||||
reason.message,
|
||||
);
|
||||
} else if (dbgReason instanceof Failure) {
|
||||
throw new Error('Cannot fail with a failure, just return it');
|
||||
} else {
|
||||
return new Failure(type, FTProps[type].message, undefined, undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,5 +13,5 @@ export function ParseMime(mime: string): Failable<FullMime> {
|
|||
if (SupportedAnimMimes.includes(mime))
|
||||
return { mime, type: SupportedMimeCategory.Animation };
|
||||
|
||||
return Fail(FT.Validation, 'Unsupported mime type');
|
||||
return Fail(FT.UsrValidation, 'Unsupported mime type');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue