【问题标题】:Endpoint returns an error, but http subscription doesnt catch it端点返回错误,但 http 订阅没有捕获它
【发布时间】:2019-03-12 17:23:32
【问题描述】:

我有一段简单的代码。

let body = new FormData();
body.set("a", true);
body.set("username", this.user);
body.set("password", this.password);

let headers = new HttpHeaders();
headers.set("Content-Type", 'application/x-www-form-urlencoded')

console.log("about to post");
this.http.post("/endpoint", body, {headers: headers}).subscribe(
    (result) => { console.log("success", result); /*extra code*/},
    (error) => { console.log("error", error); /*extra code*/ },
    () => { console.log("Complete"); /*extra code*/ });

这是一个非常简单的订阅。

所以我做了一个发布请求,它抛出了一个 401 错误网络请求。我注意到的问题是控制台会说

about to post
POST [url] 401 (Unauthorized)
Complete

它不执行错误功能。

在构造函数中http定义为:private http: HttpClient

所以我有点难以理解为什么它无法抛出错误。有什么东西不能工作吗?我正在查看类似的帖子,例如 Catching errors in Angular HttpClient,我认为我正在关注关于订阅的帖子。

在请求成功时,它调用成功就好了。

编辑 我查看了更多代码,并认为可能是数据或标题错误。所以我要在上面更新它们。似乎传递的数据看起来不对,所以我将其更新为表单数据。我穿过端点,直到它遇到一个 throw new Exception("Authorization Error"),但它从不调用错误函数。也许我在发布请求的定义中缺少一些东西?也许是因为我没有正确设置某些东西而导致内部出现问题?

【问题讨论】:

  • @DanielGimenez 我正在使用谷歌浏览器
  • 你有没有机会拦截响应?
  • @MikNiller 让我补充一下我的问题。我确实注意到打嗝了。
  • @MikNiller 我在想正文发生了变化,或者标题不正确?在端点中,它按设计工作,我看到了所有数据,但是当发生异常时,它无法执行。我应该设置另一个选项吗?

标签: angular typescript httpclient


【解决方案1】:

这里我准备了一个模拟so you can play

基本上,它使用“FakeBackendInterceptor”组件模拟拦截一些 http 请求的服务器调用。如果您向“/protected”端点发布请求,我会在此处模拟未经授权的响应。

启动应用程序的唯一组件是 HelloComponent,它调用 get 和 post 服务来模拟授权和未经授权的调用。

最后你是对的,因为它被捕获为错误。叉它,这样你就可以尝试其他任何东西。我习惯于在一个地方拦截所有错误(或未经授权的调用),我刚刚添加了一个 ErrorInterceptor 组件,因此您可以尝试两种方法。

注意 app.module 中的声明(顺序很重要):

providers:    [ 
    { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
    { provide: HTTP_INTERCEPTORS, useClass: FakeBackendInterceptor, multi: true },
  ], 

不要忘记将 HttpClientModule 添加到导入:

imports:      [ HttpClientModule, BrowserModule, FormsModule ],

如果不想使用拦截器:

  this.service.post().subscribe(
    (result) => { console.log("success", result); /*extra code*/},
    (error) => { 
      console.log("error", error); /*extra code*/ 
      if (error.status === 401)  {
        console.log("You are not authorized");
      }
    },
    () => { console.log("Complete"); /*extra code*/ })
}

我添加了另一个额外的案例,以便您可以在服务本身中处理 401。如果您发送 PUT 请求,您可以对其进行测试:

  let body = new FormData();
  body.set("a", 'true');
  body.set("username", 'user');
  body.set("password", 'password');

  let headers = this.createHeaders();
  
  console.log("calling services unauthorized PUT");
  return this.http.put<any>("/protected", body, { headers, observe: "response" }).
  pipe(
    map(res => {
    if (res.status === 400 || res.status === 401) {
      throw new Error(res.body.message);
    }
    return res.body;
  }));

【讨论】:

  • HttpHeaders 和 Headers 有区别吗?如果 401 不是错误而是状态,那么它应该触发成功吗?我会认为它是二进制的....要么执行成功功能,要么不执行。话虽如此,我认为结果至少会打印出“成功”。没有?
  • 对不起,它是 HttpHeaders 和来自 angular/common/ 的新版本。我将您指向文档,以便您可以更好地理解 HTTP 响应的内部工作原理。我所做的是添加一个组件来处理所有未经授权的响应,而不是一个一个地做。我编辑我的答案。
  • 听起来response就是成功函数。鉴于此,并且我已经声明它在调用错误时不会触发成功函数,我希望看到一个说明这个用例的功能演示。据我所知,这不是一个有效的答案。
  • 让我为你模拟一场堆栈闪电战
  • 你是对的。问题是一个拦截器,它隐藏在我们需要查看的代码库中
猜你喜欢
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多