You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express路由触发ESLint规则@typescript-eslint/no-misused-promises报错求助

问题排查:@typescript-eslint/no-misused-promises 错误分析

问题描述

执行ESLint脚本时,所有使用isAValidToken作为中间件的Express路由均抛出以下错误:

error  Promise returned in function argument where a void return was expected  @typescript-eslint/no-misused-promises

相关代码示例:

路由代码

import { getAllCards } from '../controllers/CardsController';
import express from 'express';
import { isAValidToken } from '../controllers/TokenController';
import { errorCallback } from '../controllers/ErrorController';
const router = express.Router();

router.get('/', isAValidToken, async (req, res) => {
    try {
        const cards = await getAllCards();
        res.json(cards);
    } catch (error: any) {
        errorCallback(error, res);
    }
});

TokenController核心代码

import jwt from 'jsonwebtoken';
import { API_SECRET } from '../constants/constants';
import { Request, Response, NextFunction } from 'express';

async function verifyAnyToken (token: string, secret: string): Promise<unknown> {
    return await new Promise((resolve, reject) => {
        jwt.verify(token, secret, (error) => {
            if (error != null) {
                reject(error);
            } else {
                resolve(token);
            }
        });
    });
}

async function verifyToken (token: string): Promise<unknown> {
    return await verifyAnyToken(token, API_SECRET);
}

export async function getTokenFromRequest (req: Request): Promise<string> {
    const token = req.body.token || req.headers['x-access-token'] || req.headers.authorization || req.params.token;
    return await getNormalizedToken(token);
}

export async function isAValidToken (req: Request, res: Response, next: NextFunction): Promise<void> {
    const token = await getTokenFromRequest(req);
    await verifyToken(token);
    next();
}

错误原因

  1. Express中间件的预期行为:Express的中间件函数默认期望是同步函数,或者返回void——它不会自动处理中间件返回的Promise。
  2. async函数的特性:isAValidToken被定义为async函数,这类函数无论是否显式返回值,都会默认返回一个Promise。
  3. ESLint规则触发:@typescript-eslint/no-misused-promises规则会检测到「将返回Promise的函数当作期望返回void的回调使用」的场景,因此抛出错误。

另外,当前代码还存在隐藏风险:如果verifyToken抛出错误,这个Promise的rejection不会被捕获,会导致未处理的Promise拒绝错误,进而使服务器崩溃。

解决方案

方案一:正确处理异步中间件的错误

修改isAValidToken,手动捕获异步逻辑的错误并传递给Express的错误处理中间件,确保Promise的状态被正确处理:

export async function isAValidToken (req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
        const token = await getTokenFromRequest(req);
        await verifyToken(token);
        next();
    } catch (error) {
        // 将错误传递给Express全局错误处理中间件
        next(error);
    }
}

此时可以保留async函数,因为我们已经正确处理了所有可能的错误,ESLint不会再触发该规则(若仍触发,可在ESLint配置中对Express中间件场景放宽该规则)。

方案二:转换为回调风格的同步中间件

如果偏好Express传统的回调模式,可以将异步逻辑包装为链式调用,避免返回Promise:

export function isAValidToken (req: Request, res: Response, next: NextFunction): void {
    getTokenFromRequest(req)
        .then(token => verifyToken(token))
        .then(() => next())
        .catch(error => next(error));
}

这种方式下函数返回void,完全符合Express中间件的预期,ESLint规则不会触发。

内容的提问来源于stack exchange,提问作者Daniel Corona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 12:15:33