Skip to content

Commit

Permalink
refactor: exception
Browse files Browse the repository at this point in the history
  • Loading branch information
kuizuo committed Aug 3, 2023
1 parent d347182 commit d259ed2
Show file tree
Hide file tree
Showing 39 changed files with 296 additions and 245 deletions.
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch via NPM",
"request": "launch",
"runtimeArgs": [
"run",
"dev"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}
]
}
43 changes: 43 additions & 0 deletions apps/api/src/constants/error-code.constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export enum ErrorEnum {
DEFAULT = '0:未知错误',
SERVER_ERROR = '500:服务繁忙,请稍后再试',

SYSTEM_USER_EXISTS = '1001:系统用户已存在',
INVALID_VERIFICATION_CODE = '1002:验证码填写有误',
INVALID_USERNAME_PASSWORD = '1003:用户名密码有误',
NODE_ROUTE_EXISTS = '1004:节点路由已存在',
PERMISSION_REQUIRES_PARENT = '1005:权限必须包含父节点',
ILLEGAL_OPERATION_DIRECTORY_PARENT = '1006:非法操作:该节点仅支持目录类型父节点',
ILLEGAL_OPERATION_CANNOT_CONVERT_NODE_TYPE = '1007:非法操作:节点类型无法直接转换',
ROLE_HAS_ASSOCIATED_USERS = '1008:该角色存在关联用户,请先删除关联用户',
DEPARTMENT_HAS_ASSOCIATED_USERS = '1009:该部门存在关联用户,请先删除关联用户',
DEPARTMENT_HAS_ASSOCIATED_ROLES = '1010:该部门存在关联角色,请先删除关联角色',
PASSWORD_MISMATCH = '1011:旧密码与原密码不一致',
LOGOUT_OWN_SESSION = '1012:如想下线自身可右上角退出',
NOT_ALLOWED_TO_LOGOUT_USER = '1013:不允许下线该用户',
PARENT_MENU_NOT_FOUND = '1014:父级菜单不存在',
DEPARTMENT_HAS_CHILD_DEPARTMENTS = '1015:该部门存在子部门,请先删除子部门',
SYSTEM_BUILTIN_FUNCTION_NOT_ALLOWED = '1016:系统内置功能不允许操作',
USER_NOT_FOUND = '1017:用户不存在',
UNABLE_TO_FIND_DEPARTMENT_FOR_USER = '1018:无法查找当前用户所属部门',
DEPARTMENT_NOT_FOUND = '1019:部门不存在',
PARAMETER_CONFIG_KEY_EXISTS = '1021:参数配置键值对已存在',
DEFAULT_ROLE_NOT_FOUND = '1022:所分配的默认角色不存在',

INVALID_LOGIN = '1101:登录无效,请重新登录',
NO_PERMISSION = '1102:无权限访问',
ONLY_ADMIN_CAN_LOGIN = '1103:不是管理员,无法登录',
REQUEST_INVALIDATED = '1104:当前请求已失效',
ACCOUNT_LOGGED_IN_ELSEWHERE = '1105:您的账号已在其他地方登录',
GUEST_ACCOUNT_RESTRICTED_OPERATION = '1106:游客账号不允许操作',
REQUESTED_RESOURCE_NOT_FOUND = '1107:所请求的资源不存在',

TOO_MANY_REQUESTS = '1201:请求频率过快,请一分钟后再试',
MAXIMUM_FIVE_VERIFICATION_CODES_PER_DAY = '1202:一天最多发送5条验证码',
VERIFICATION_CODE_SEND_FAILED = '1203:验证码发送失败',

INSECURE_MISSION = '1301:不安全的任务,确保执行的加入@Mission注解',
EXECUTED_MISSION_NOT_FOUND = '1302:所执行的任务不存在',
MISSION_EXECUTION_FAILED = '1303:任务执行失败',
MISSION_NOT_FOUND = '1304:任务不存在',
}
51 changes: 0 additions & 51 deletions apps/api/src/constants/error.ts

This file was deleted.

File renamed without changes.
6 changes: 0 additions & 6 deletions apps/api/src/constants/role.ts

This file was deleted.

File renamed without changes.
47 changes: 0 additions & 47 deletions apps/api/src/constants/type.ts

This file was deleted.

34 changes: 23 additions & 11 deletions apps/api/src/exceptions/api.exception.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import { HttpException, HttpStatus } from '@nestjs/common';

import { ErrorEnum } from '../constants/error';
import { ErrorEnum } from '../constants/error-code.constant';

/**
* 业务错误时可抛出该异常
*/
export class ApiException extends HttpException {
private errorCode: number;

/**
* 业务错误,请求结果仍为200
*/
constructor(err: ErrorEnum) {
super(`${err}`, HttpStatus.OK);
// CODE_500 str parse to 500 number
this.errorCode = Number(
Object.entries(ErrorEnum)
.find(([_, val]) => val === err)[0]
.replace('CODE_', ''),
constructor(error: ErrorEnum | string) {
if (!error.includes(':')) {
super(
HttpException.createBody({
code: 0,
message: error,
}),
HttpStatus.OK,
);
this.errorCode = 0;
return;
}

const [code, message] = error.split(':');
super(
HttpException.createBody({
code,
message,
}),
HttpStatus.OK,
);

this.errorCode = Number(code);
}

getErrorCode(): number {
Expand Down
33 changes: 25 additions & 8 deletions apps/api/src/exceptions/socket.exception.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
import { HttpException } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';

import { ErrorEnum } from '../constants/error';
import { ErrorEnum } from '../constants/error-code.constant';

export class SocketException extends WsException {
private errorCode: number;

constructor(err: ErrorEnum) {
super(`${err}`);
// CODE_500 str parse to 500 number
this.errorCode = Number(
Object.entries(ErrorEnum)
.find(([_, val]) => val === err)[0]
.replace('CODE_', ''),
constructor(message: string);
constructor(error: ErrorEnum);
constructor(...args: any) {
const error = args[0];
if (typeof error === 'string') {
super(
HttpException.createBody({
code: 0,
message: error,
}),
);
this.errorCode = 0;
return;
}

const [code, message] = error.split(':');
super(
HttpException.createBody({
code,
message,
}),
);

this.errorCode = Number(code);
}

getErrorCode(): number {
Expand Down
31 changes: 24 additions & 7 deletions apps/api/src/filters/app.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,25 @@ import {
ExceptionFilter,
HttpException,
HttpStatus,
Logger,
} from '@nestjs/common';
import { FastifyReply } from 'fastify';

import { ErrorEnum } from '../constants/error';
import { ApiException } from '../exceptions/api.exception';
import { ErrorEnum } from '@/constants/error-code.constant';
import { ApiException } from '@/exceptions/api.exception';
import { isDev } from '@/global/env';

@Catch()
export class AppFilter implements ExceptionFilter {
private readonly logger = new Logger(AppFilter.name);

constructor() {
this.registerCatchAllExceptionsHook();
}

catch(exception: unknown, host: ArgumentsHost) {
this.logger.error(exception);

const ctx = host.switchToHttp();
const response = ctx.getResponse<FastifyReply>();

Expand All @@ -29,11 +39,8 @@ export class AppFilter implements ExceptionFilter {
exception instanceof HttpException ? exception.message : `${exception}`;

// 系统内部错误时,在生产模式下隐藏具体异常消息
if (
process.env.NODE_ENV === 'production' &&
httpStatus === HttpStatus.INTERNAL_SERVER_ERROR
) {
errorMessage = ErrorEnum.CODE_500;
if (!isDev && httpStatus === HttpStatus.INTERNAL_SERVER_ERROR) {
errorMessage = ErrorEnum.SERVER_ERROR?.split(':')[1];
}

// 返回基础响应结果
Expand All @@ -45,4 +52,14 @@ export class AppFilter implements ExceptionFilter {

response.status(httpStatus).send(resBody);
}

registerCatchAllExceptionsHook() {
process.on('unhandledRejection', (reason: any) => {
console.error('unhandledRejection: ', reason);
});

process.on('uncaughtException', (err) => {
console.error('uncaughtException: ', err);
});
}
}
11 changes: 11 additions & 0 deletions apps/api/src/global/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import cluster from 'cluster';

export const isMainCluster =
process.env.NODE_APP_INSTANCE &&
parseInt(process.env.NODE_APP_INSTANCE) === 0;
export const isMainProcess = cluster.isPrimary || isMainCluster;

export const isDev = process.env.NODE_ENV === 'development';

export const isTest = !!process.env.TEST;
export const cwd = process.cwd();
Empty file.
6 changes: 2 additions & 4 deletions apps/api/src/modules/apps/todo/todo.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Injectable } from '@nestjs/common';
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { ErrorEnum } from '@/constants/error';
import { ApiException } from '@/exceptions/api.exception';
import { paginate } from '@/helper/paginate';
import { Pagination } from '@/helper/paginate/pagination';
import { TodoEntity } from '@/modules/apps/todo/todo.entity';
Expand All @@ -27,7 +25,7 @@ export class TodoService {

async detail(id: number): Promise<TodoEntity> {
const item = await this.todoRepository.findOneBy({ id });
if (!item) throw new ApiException(ErrorEnum.CODE_2004);
if (!item) throw new NotFoundException('未找到该记录');

return item;
}
Expand Down
Loading

0 comments on commit d259ed2

Please sign in to comment.