NestJS - 请求超时
Posted
技术标签:
【中文标题】NestJS - 请求超时【英文标题】:NestJS - request timeout 【发布时间】:2018-08-17 16:21:01 【问题描述】:如何为所有请求设置超时,如果超时则使用自定义 json 响应?
我尝试使用:
import * as timeout from 'connect-timeout';
import NestFactory from '@nestjs/core';
import ApplicationModule from './app.module';
const port = process.env.PORT || 3020;
async function bootstrap()
const app = await NestFactory.create(ApplicationModule);
app.use(timeout('5s'));
app.use(haltOnTimedOut);
await app.listen(port);
bootstrap();
function haltOnTimedOut (req, res, next)
if (!req.timedout)
next();
else
res
.status(408)
.json( status: 'error', data: 'timeout')
但没有运气。
【问题讨论】:
【参考方案1】:为了增加 nestjs - API 应用服务器请求/响应超时,我在 main.js 中做了以下操作
const server = await app.listen(5000);
server.setTimeout(1800000); // 600,000=> 10Min, 1200,000=>20Min, 1800,000=>30Min
【讨论】:
谢谢!解决了我的问题!你也可以这样做:server.setTimeout(30 * 60 * 1000);【参考方案2】:NestJS 有一个称为拦截器的功能。拦截器可用于强制超时,他们在这里演示,TimeoutInterceptor。
假设您将拦截器放在一个名为 timeout.interceptor.ts
的文件中:
import Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException from '@nestjs/common';
import Observable, throwError, TimeoutError from 'rxjs';
import catchError, timeout from 'rxjs/operators';
@Injectable()
export class TimeoutInterceptor implements NestInterceptor
intercept(context: ExecutionContext, next: CallHandler): Observable<any>
return next.handle().pipe(
timeout(5000),
catchError(err =>
if (err instanceof TimeoutError)
return throwError(new RequestTimeoutException());
return throwError(err);
),
);
;
;
在此之后,您必须注册它,这可以通过多种方式完成。全局注册方式如下图:
const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new TimeoutInterceptor());
【讨论】:
这种方法的问题是很多代码可以在拦截器之前运行(例如你的守卫或中间件),你仍然希望你的超时适用于那些。【参考方案3】:您可以将 express 实例传递给 NextFactory.create(module, expressInstance)
,这样您就可以将中间件添加到该 express 实例中,例如
const expressInstance = express();
express.use(timeout('4'));
express.use((err, res, req, next) => req.jsonp(err)); // DON'T USE FOR PRODUCTION
const app = NestFactory.create(AppModule, express);
它应该可以工作。
【讨论】:
即使我的解决方案超时有效,但我无法将默认响应从 html 更改为我提供的 json。 github.com/expressjs/timeout/blob/master/index.js#L82 如果您检查此代码,则会将错误返回到由错误处理程序处理的中间件。您可以编写这样的函数(err, res, req, next) => req.jsonp(err)
,以便解决。注意:不要在生产中使用这个使用你自己的错误处理程序【参考方案4】:
将app.use(timeout('5s'));
移出bootstrap
函数,并同时从haltOnTimedOut
函数中删除else
块。
并尝试将您的 bootstrap
函数作为中间件调用,如下所示,
app.use(boostrap, timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next)
if (req.timedout) return
res
.status(408)
.json( status: 'error', data: 'timeout')
);
希望这会有所帮助!
【讨论】:
如果应用程序在引导函数中定义,应用程序如何使用引导程序?以上是关于NestJS - 请求超时的主要内容,如果未能解决你的问题,请参考以下文章