Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js NestJS:截取器映射和捕获错误_Node.js_Typescript_Express_Rxjs_Nestjs - Fatal编程技术网

Node.js NestJS:截取器映射和捕获错误

Node.js NestJS:截取器映射和捕获错误,node.js,typescript,express,rxjs,nestjs,Node.js,Typescript,Express,Rxjs,Nestjs,我需要一个NestJS拦截器来存档请求,无论是在异常情况下还是在快乐路径情况下。创建如下: public intercept(context: ExecutionContext, next: CallHandler): Observable<any> { if (!this.reflector.get<boolean>(RequestMetaData.IS_PUBLIC_ROUTE, context.getHandler())) { return

我需要一个NestJS拦截器来存档请求,无论是在异常情况下还是在快乐路径情况下。创建如下:

public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {

    if (!this.reflector.get<boolean>(RequestMetaData.IS_PUBLIC_ROUTE, context.getHandler())) {
        return next.handle().pipe(
          map(data => {
              const host = context.switchToHttp();
              const req = host.getRequest();
              const resp = host.getResponse();
              this.persistRequest(data, req, resp)
                .then(() => this.logger.log(`Request logged`))
                .catch(e => {
                    this.logger.error(`Error logging request: ${e.message}`);
                });
              return data;
          }));
    }
    return next.handle();
}
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {

    if (!this.reflector.get<boolean>(RequestMetaData.IS_PUBLIC_ROUTE, context.getHandler())) {

        const host = context.switchToHttp();
        const req = host.getRequest();
        const resp = host.getResponse();

        return next.handle().pipe(
          tap({
              next: (val) => {
                  this.persistRequest(val, req, resp);
              },
              error: (error) => {
                  this.persistRequest(AppError.from(error), req, resp);
              }
          })
        );
    }
    return next.handle();
}
public intercept(context:ExecutionContext,next:CallHandler):可观察{
if(!this.reflector.get(RequestMetaData.IS\u PUBLIC\u ROUTE,context.getHandler())){
返回next.handle().pipe(
地图(数据=>{
const host=context.switchToHttp();
const req=host.getRequest();
const resp=host.getResponse();
持久化请求(数据、请求、响应)
.then(()=>this.logger.log(`Request logged`))
.catch(e=>{
this.logger.error(`error logging request:${e.message}`);
});
返回数据;
}));
}
返回next.handle();
}
问题:

这只记录了快乐之路。因为我不熟悉RxJS,所以我创建了另一个来保存错误。例如:

public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => {
            return throwError(err);
        })
      );
}
public intercept(context:ExecutionContext,next:CallHandler):可观察{
下一个返回
.handle()
.烟斗(
catchError(err=>{
回程抛掷器(err);
})
);
}

如何定义一个对两条路径进行存档的拦截器

我认为您在这里使用了错误的运算符。内部映射还返回一个发布者

您应该使用
flatMap
转换外部发布服务器,以便创建一个流,而不是嵌套流

以下是纯RxJS 6中的一个示例:

import { of, EMPTY } from 'rxjs';
import { map, flatMap, catchError } from 'rxjs/operators';

of(3,2,1,0,1,2,3).pipe(
  flatMap(v => {
    return of(v).pipe(
      map(x => {    
        if(x===0) throw Error();
        return 6 / x;
      }), 
      catchError(error => {
        console.log("Shit happens")
        return EMPTY
      }
    )
    )
  } 
))
.subscribe(val => console.log("Request " + val + " logged "));
每个请求(这里是数字)都是一个平面图,映射成一个持久化的东西。 平面映射意味着,持久化器再次返回一个可观察的对象。看

这些内部观测值的错误处理通过
catchError
操作符完成。它记录错误,然后返回一个空的可观察对象,以指示内部可观察对象是“死的”。你可以在这里返回另一个可观察到的,然后内部将继续

外部可观察到的,即您传入的请求,将在一路上继续进行

我在这里创建了一个stackblitz应用程序:

祝NestJS和所有不同版本的RxJS好运。以上是第6版

编辑:

RxJS
tap
方法是处理副作用的好方法。执行截取方法如下:

public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {

    if (!this.reflector.get<boolean>(RequestMetaData.IS_PUBLIC_ROUTE, context.getHandler())) {
        return next.handle().pipe(
          map(data => {
              const host = context.switchToHttp();
              const req = host.getRequest();
              const resp = host.getResponse();
              this.persistRequest(data, req, resp)
                .then(() => this.logger.log(`Request logged`))
                .catch(e => {
                    this.logger.error(`Error logging request: ${e.message}`);
                });
              return data;
          }));
    }
    return next.handle();
}
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {

    if (!this.reflector.get<boolean>(RequestMetaData.IS_PUBLIC_ROUTE, context.getHandler())) {

        const host = context.switchToHttp();
        const req = host.getRequest();
        const resp = host.getResponse();

        return next.handle().pipe(
          tap({
              next: (val) => {
                  this.persistRequest(val, req, resp);
              },
              error: (error) => {
                  this.persistRequest(AppError.from(error), req, resp);
              }
          })
        );
    }
    return next.handle();
}
public intercept(context:ExecutionContext,next:CallHandler):可观察{
if(!this.reflector.get(RequestMetaData.IS\u PUBLIC\u ROUTE,context.getHandler())){
const host=context.switchToHttp();
const req=host.getRequest();
const resp=host.getResponse();
返回next.handle().pipe(
水龙头({
下一步:(val)=>{
该请求(val、req、resp);
},
错误:(错误)=>{
此.persistRequest(AppError.from(error)、req、resp);
}
})
);
}
返回next.handle();
}

嘿,迈克尔!最近怎么样?你能举个例子吗?我没听懂,一切都很好。我更新了我的答案,以澄清这个概念。希望能有帮助。我最后使用了tap-谢谢你为我指明了正确的方向。顺便说一句,我使用的最后一个FRP框架是Objective-C的框架——我认为它被称为反应性Cocoa。