node+ts+express 构建 RESTful API 之 错误处理

简景焕
2023-12-01

使用TypeScript+Express+NodeJS+MongoDB 开发 Web APIs,如有错误可以击提issue ,如果觉得ok,请点个star , 送人玫瑰、手有余香
仓库地址 ➡️FE_note

本系列文章

  1. 搭建环境
  2. 构建路由
  3. 连接数据库
  4. nodeJs 错误处理
  5. 权限认证与数据加密

nodeJs错误处理

通过上面的学习,存在一个很大问题,就是我们把操作数据库的错误抛给了client这种实践是非常糟糕的,现在我们封装一个错误处理的中间件。

首先,让我们创建一个将用于引发错误的类。

src/exceptions/HttpException.ts

class HttpException extends Error{
    constructor(public status:number,public message:string){
        super(message);
        this.status=status;
        this.message=message
    }
}
export default HttpException

如果您想了解有关Error对象和一般错误的更多信息,请尝试使用try…catch检查 JavaScript处理错误,最后

接下来,书写错误中间件

middleware/error.middleware.ts

import {Request,Response,NextFunction} from 'express'
import HttpException from '../expceptions/httpException'
function errorMiddleware(error:HttpException,request:Request,response:Response,next:NextFunction){
    const status=error.status||500;
    const message=error.message||'Something went wrong';
    response
        .status(status)
        .send({
            status,
            message
        })
}
export default errorMiddleware

引入中间件

app.ts

import express from 'express' 
import {json,urlencoded} from 'body-parser'
import cors from 'cors'
import morgan from 'morgan'
import routes from './routes'
import mongoose from 'mongoose';
import errorMiddleware from './middleware/error.middleware'
import {DB_URL} from './config'

class App{
    public app:express.Application;
    constructor(){
        this.app=express();
        this.config()
        this.setMongoConfig()
        
        // 引入路由
        this.app.use(routes)

        //错误处理
        this.initializeErrorHandling();
    }

    private config(){
        //开启 cors
        this.app.use(cors())
        //支持  application/json类型 发送数据
        this.app.use(json());
        //支持 application/x-www-form-urlencoded 发送数据
        this.app.use(urlencoded({extended:false}))
        //日志中间件
        this.app.use(morgan('dev'))
    }
    
    private initializeErrorHandling(){
        this.app.use(errorMiddleware)
    }

    private setMongoConfig(){
        mongoose.Promise = global.Promise;
        mongoose.connect(DB_URL, {
            useNewUrlParser: true
          });
    }

}
export default new App().app

应用
controllers/userController.ts

import HttpException from '../expceptions/httpException'

class UserController{
    static getOneById=async(req:Request,res:Response,next:NextFunction)=>{
        const id=req.params.id;
        User.findById(id,(err,userInfo)=>{
            if(err){
                next(new HttpException(404,`id:${id},not found`))
            }else{
                res.send(userInfo)

            }            
        })
    }
}

对于404页面我们可以再进一步抽离出一个notFoundException类。

expceptions/NotFoundException.ts

import HttpException from './HttpException'

class NotFoundException extends HttpException{
    constructor(id:string){
        super(404,`id:${id},not found`);
    }
}
export default NotFoundException

进一步修改controller

controllers/userController.ts

import NotFoundException from '../expceptions/NotFoundException'

class UserController{
    static getOneById=async(req:Request,res:Response,next:NextFunction)=>{
        const id=req.params.id;
        User.findById(id,(err,userInfo)=>{
            if(err){
                next(new NotFoundException(id))
            }else{
                res.send(userInfo)
            }
        })
    }
}

下篇 权限认证

 类似资料: