当查询失败时如何捕获nestjs中的错误

apu*_*pun 7 postgresql typeorm nestjs

我是新手nestjs,正在尝试将我的后端从 转换nodejsnestjs. 希望这是有道理的吗?我正在使用`typeorm. 但我不确定捕获错误的最佳方法是什么。

entity.ts

import { Entity, Column, PrimaryGeneratedColumn, PrimaryColumn } from 'typeorm';

@Entity()
export class Course {

  @PrimaryColumn()
  course: string;

  @Column("varchar", { array: true })
  subject: string[];
}
Run Code Online (Sandbox Code Playgroud)

controller.ts

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CourseService } from './course.service';
import { Course } from './course.entity';

@Controller('course')
export class CourseController {
    constructor(private courseService: CourseService) {}

    @Get()
    getCourses(): Promise<Course[]> {
        return this.courseService.findAll();
    }

    @Post()
    addCourse(@Body() courseDto: Course[]) {
        return this.courseService.create(courseDto);
    }
}
Run Code Online (Sandbox Code Playgroud)

service.ts

import { Injectable, Catch, ExceptionFilter, ArgumentsHost, ConflictException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, QueryFailedError } from 'typeorm';
import { Course } from './course.entity';

@Injectable()
export class CourseService {
    constructor(
        @InjectRepository(Course)
        private courseRepository: Repository<Course>,
    ) { }

    catch(exception: any, host: ArgumentsHost) {
        throw new Error("Error in course service." + exception.code);
    }

    findAll(): Promise<Course[]> {
        return this.courseRepository.find();
    }

    create(courseDto) {
        return this.courseRepository.insert(courseDto)
            .catch((err: any) => {
                // throw new ConflictException();

                switch (err.name) {
                    case 'QueryFailedError':
                        console.log("**++**" + JSON.stringify(err));
                        // throw new Error("Error" + err.message + "" + err.detail);
                        // throw new ConflictException();
                        throw JSON.stringify(err); //"Error creating a course" + err.message + "::: " + err.detail;
                    default:
                        throw err; 

                }
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我能扔的就是throw new ConflictException();。我想根据结果抛出不同的错误,例如 - 1. 对于重复记录 2. 缺少必填字段 3. 等等

但不知道我们如何处理和定制它并充分利用nestjs。

就像我在控制台中看到以下跟踪一样,但是500, Internal server in postman-

{"message":"duplicate key value violates unique constraint \"PK_d7fc152bc721b3f55a56ed3ad33\"","name":"QueryFailedError","length":293,"severity":"ERROR","code":"23505","detail":"Key (course)=(II) already exists.","schema":"public","table":"course","constraint":"PK_d7fc152bc721b3f55a56ed3ad33","file":"d:\\pginstaller.auto\\postgres.windows-x64\\src\\backend\\access\\nbtree\\nbtinsert.c","line":"535","routine":"_bt_check_unique","query":"INSERT INTO \"course\"(\"course\", \"subject\") VALUES ($1, $2)","parameters":["II",["A","B","C"]]}
[Nest] 12152   - 04/10/2020, 1:18:40 PM   [ExceptionsHandler] {"message":"duplicate key value violates unique constraint \"PK_d7fc152bc721b3f55a56ed3ad33\"","name":"QueryFailedError","length":293,"severity":"ERROR","code":"23505","detail":"Key (course)=(II) already exists.","schema":"public","table":"course","constraint":"PK_d7fc152bc721b3f55a56ed3ad33","file":"d:\\pginstaller.auto\\postgres.windows-x64\\src\\backend\\access\\nbtree\\nbtinsert.c","line":"535","routine":"_bt_check_unique","query":"INSERT INTO \"course\"(\"course\", \"subject\") VALUES ($1, $2)","parameters":["II",["A","B","C"]]} +190924ms
Run Code Online (Sandbox Code Playgroud)

小智 14

如何将错误传递给控制器​​并让控制器抛出这些错误。

服务.ts

create(courseDto) {
  return this.courseRepository.insert(courseDto)
}
Run Code Online (Sandbox Code Playgroud)

并在你的controller.ts中

import {
  Controller,
  Get,
  Post,
  HttpException,
  HttpStatus,
} from '@nestjs/common';

...

@Post()
async addCourse(@Body() courseDto: Course[]) {
    return await this.courseService.create(courseDto).catch(err => {
      throw new HttpException({
        message: err.message
      }, HttpStatus.BAD_REQUEST);
    })
}
Run Code Online (Sandbox Code Playgroud)

https://docs.nestjs.com/exception-filters

  • 从设计的角度来看,我不会支持这个解决方案。在六边形架构中,端点(即控制器)只是访问业务层的**一种**方式。如果您为服务添加 CLI 命令或(留在 Web 上下文中)GraphQL 解析器,您将需要为每个入口点重新构建所有错误处理。当异常对业务至关重要时,最好让服务层处理它们。即,当服务需要一个实体来获取/持久并且它失败时,就让它失败。 (9认同)