Rxjs 如何在可观察的NestJS中引发异常?

Rxjs 如何在可观察的NestJS中引发异常?,rxjs,nestjs,Rxjs,Nestjs,开始使用NestJS时遇到了一个问题,如何在Observable中抛出异常 public getGuild(guildId: string, token: string): Observable<Guild | undefined> { const guild = this.httpService .get<Guild[]>(url, { headers: { authorization: token }, }) .pipe(map

开始使用NestJS时遇到了一个问题,如何在Observable中抛出异常

public getGuild(guildId: string, token: string): Observable<Guild | undefined> {
  const guild = this.httpService
    .get<Guild[]>(url, {
      headers: { authorization: token },
    })
    .pipe(map((result) => result.data.find((guild) => guild.id === guildId)));

  return guild;
}
public-getGuild(guildId:string,token:string):可观察{
const guild=this.httpService
.get(url{
标头:{授权:令牌},
})
.pipe(map((result)=>result.data.find((guild)=>guild.id==guildId));
回归公会;
}
来自外部API的响应可以是未定义的,如何正确检查它,如果未定义,如何使用404代码使NestJS响应

如果您只是在控制器中返回此响应,即使响应未定义,NestJS也会返回代码200


我以前从未遇到过RxJS,所以我无法解决这个问题。HttpModule文档也没有对此做任何说明。

如果您希望从可观察对象中抛出异常,可以这样做

返回此.httpService
.get(url、选项)
.烟斗(
映射(response=>response.data),
地图(数据=>{
如果(数据===未定义){
抛出新的NotFoundException();
}
返回数据;
),
);

如果您希望从observable中抛出异常,您可以这样做

返回此.httpService
.get(url、选项)
.烟斗(
映射(response=>response.data),
地图(数据=>{
如果(数据===未定义){
抛出新的NotFoundException();
}
返回数据;
),
);

您可以在流中的任何点抛出错误。如果
结果,以下代码段将抛出错误。数据
不包含带有传入的
guildId
的帮会。现在您的结果将被定义(非空/未定义)或错误

public getGuild(guildId: string, token: string): Observable<Guild> {
  return this.httpService.get<Guild[]>(url, {
    headers: { authorization: token },
  }).pipe(
    map(result => 
      result.data.find(guild => guild.id === guildId)
    ),
    tap(guild => {
      if(guild == null) throw new Error(`No guild with ${guildId} found`);
    })
  );
}
在这种情况下,您的流不再是“纯”的,因为您无法具体说明这是什么。globalValue将是什么(可能在您阅读之前,其他代码块会再次更改此全局值)。这使得测试变得困难。您失去了RxJS函数式的许多好处

如果将
tap(x=>doSomething)
替换为
map(x=>{doSomething;return x})
,则所有这些问题都是相同的。然而,按照习惯,程序员可能会花更多时间理解
map
在做什么,因为他们可能期望
tap
没有控制流


主观部分 在我看来,
tap
是一个抛出错误的好地方。它应该告诉任何阅读/更新代码的开发人员“这个错误是由流中此时的值的形状产生的”。像验证和日志记录这样的事情非常适合(习惯用法)在RxJS中,
点击
操作符。在验证过程中抛出错误是很自然的

如何编写自定义断言操作符(您可以将它们全部剥离用于生产构建,而不用担心会破坏任何东西)

我得说,这很清楚。不过我们可以研究一个更好的错误消息


另一种避免争论的方法 如果您不想那样使用
tap
,这里有另一种方法可以用非常地道的RxJS编写它

public getGuild(guildId: string, token: string): Observable<Guild> {
  return this.httpService.get<Guild[]>(url, {
    headers: { authorization: token },
  }).pipe(
    map(result => {
      const guild = result.data.find(guild => guild.id === guildId);
      if(guild == null) throw new Error(`No guild with ${guildId} found`);
      return guild;
    })
  );
}
public-getGuild(guildId:string,token:string):可观察{
返回此.httpService.get(url{
标头:{授权:令牌},
}).烟斗(
映射(结果=>{
const guild=result.data.find(guild=>guild.id==guildId);
如果(guild==null)抛出新错误(`No guild with${guildId}found`);
回归公会;
})
);
}

现在-错误被抛出为“我未能将结果:Guild[]映射到Guild:Guild”错误。

您可以在流中的任何点抛出错误。如果
结果出现,以下代码段将抛出错误。数据
不包含具有传入的
guildId
的公会。现在您的结果将被定义(非空/未定义),或错误

public getGuild(guildId: string, token: string): Observable<Guild> {
  return this.httpService.get<Guild[]>(url, {
    headers: { authorization: token },
  }).pipe(
    map(result => 
      result.data.find(guild => guild.id === guildId)
    ),
    tap(guild => {
      if(guild == null) throw new Error(`No guild with ${guildId} found`);
    })
  );
}
在这种情况下,您的流不再是“纯”的,因为您无法具体说明这是什么。globalValue将是什么(可能在您阅读之前,其他代码块会再次更改此全局值)。这使得测试变得困难。您失去了RxJS函数式的许多好处

如果将
tap(x=>doSomething)
替换为
map(x=>{doSomething;return x})
,则所有这些问题都是相同的。然而,按照习惯,程序员可能会花更多时间理解
map
在做什么,因为他们可能期望
tap
没有控制流


主观部分 在我看来,
tap
是一个抛出错误的好地方。它应该告诉任何阅读/更新代码的开发人员“这个错误是由流中此时的值的形状产生的”。像验证和日志记录这样的事情非常适合(习惯用法)在RxJS中,
点击
操作符。在验证过程中抛出错误是很自然的

如何编写自定义断言操作符(您可以将它们全部剥离用于生产构建,而不用担心会破坏任何东西)

我得说,这很清楚。不过我们可以研究一个更好的错误消息


另一种避免争论的方法 如果您不想那样使用
tap
,这里有另一种方法可以用非常地道的RxJS编写它

public getGuild(guildId: string, token: string): Observable<Guild> {
  return this.httpService.get<Guild[]>(url, {
    headers: { authorization: token },
  }).pipe(
    map(result => {
      const guild = result.data.find(guild => guild.id === guildId);
      if(guild == null) throw new Error(`No guild with ${guildId} found`);
      return guild;
    })
  );
}
public-getGuild(guildId:string,token:string):可观察{
返回此.httpService.get(url{
标头:{授权:令牌},
}).烟斗(
映射(结果=>{
const guild=result.data.find(guild=>guild.id==guildId);
如果(guild==null)抛出新错误(`No guild with${guildId}found`);
回归公会;
})
);
}

现在-该错误被抛出为“我未能将结果:Guild[]映射到Guild:Guild”错误。

您是否尝试过
console.log(Guild)
?您应该看到类似于可观察的{u isScalar:fa
public getGuild(guildId: string, token: string): Observable<Guild> {
  return this.httpService.get<Guild[]>(url, {
    headers: { authorization: token },
  }).pipe(
    map(result => {
      const guild = result.data.find(guild => guild.id === guildId);
      if(guild == null) throw new Error(`No guild with ${guildId} found`);
      return guild;
    })
  );
}