💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 基础搭建 ### MVC配置 ``` // 安装模板 yarn add ejs --save // main.ts import { join } from 'path'; import { NestFactory } from '@nestjs/core'; // 引入app模块 import { AppModule } from './app.module'; import { HttpExceptionFilter } from './common/filters/http-exception.filter'; import { ApiParamsValidationPipe } from './common/pipe/api-params-validation.pipe'; import { NestExpressApplication } from "@nestjs/platform-express"; async function bootstrap() { // 工厂方式创建服务器 const app = await NestFactory.create<NestExpressApplication>(AppModule); //设置 视图层 app.useStaticAssets(join(__dirname, '.', 'public')); app.setBaseViewsDir(join(__dirname, '.', 'views')); app.setViewEngine('ejs'); // 设置错误处理 app.useGlobalFilters(new HttpExceptionFilter()); app.useGlobalPipes(new ApiParamsValidationPipe()); await app.listen(3001); // 使用3000端口监听应用程序 } bootstrap(); // 启动应用程序 -> localhost:3000 ~~~ ``` ### 错误处理 #### 全局错误代码 api-error-code.enum.ts ``` export enum ApiErrorCode { TIMEOUT = -1, // 系统繁忙 SUCCESS = 0, // 成功 USER_ID_INVALID = 10001, // 用户id无效 USER_NAME_HAVA = 10002, // 用户已经存在 USER_NAME_NO = 10003, // 用户无效 USER_NICKNAME_NO = 10004, // 用户昵称无效 USER_EMAIL_NO = 10005 // 用户邮箱无效 } ``` #### 全局过滤错误 http-exception.filter.ts ``` import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'; import { ApiException } from '../exceptions/api.exception'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); const request = ctx.getRequest(); const status = exception.getStatus(); if (exception instanceof ApiException) { response .status(status) .json({ errorCode: exception.getErrorCode(), errorMessage: exception.getErrorMessage(), date: new Date().toLocaleDateString(), path: request.url, }); } else { response .status(status) .json({ statusCode: status, date: new Date().toLocaleDateString(), path: request.url, }); } } } ``` #### 全局管道错误 api-params-validation.pipe.ts ``` import { ArgumentMetadata, PipeTransform, Injectable, HttpStatus } from '@nestjs/common'; import { ApiException } from '../exceptions/api.exception'; import { plainToClass } from 'class-transformer'; import { validate } from 'class-validator'; @Injectable() export class ApiParamsValidationPipe implements PipeTransform { async transform(value: any, metadata: ArgumentMetadata) { const { metatype } = metadata; // 如果参数不是 类 而是普通的 JavaScript 对象则不进行验证 if (!metatype || !this.toValidate(metatype)) { return value; } // 通过元数据和对象实例,去构建原有类型 const object = plainToClass(metatype, value); const errors = await validate(object); if (errors.length > 0) { // 获取到第一个没有通过验证的错误对象 const error = errors.shift(); const constraints = error.constraints; const contexts = error.contexts; // 将未通过验证的字段的错误信息和状态码,以ApiException的形式抛给我们的全局异常过滤器 for (const key in constraints) { throw new ApiException(constraints[key], contexts[key].errorCode, HttpStatus.BAD_REQUEST); } } return value; } private toValidate(metatype): boolean { const types = [String, Boolean, Number, Array, Object]; return !types.find((type) => metatype === type); } } ``` #### 获取错误 api.exception.ts ``` import { HttpException, HttpStatus } from '@nestjs/common'; import { ApiErrorCode } from '../enums/api-error-code.enum'; export class ApiException extends HttpException { private errorMessage: string; private errorCode: ApiErrorCode; constructor(errorMessage: string, errorCode: ApiErrorCode, statusCode: HttpStatus) { super(errorMessage, statusCode); this.errorMessage = errorMessage; this.errorCode = errorCode; } getErrorCode(): ApiErrorCode { return this.errorCode; } getErrorMessage(): string { return this.errorMessage; } } ```