遇到非HTTP错误时,rxResource会一直处于加载状态

前端开发 2026-07-09

我正在尝试使用Angular的 rxResource 来处理HTTP请求,主要是为了在显示上获得更好的易用性,利用 rxResourcehasValue()errorisLoading()

虽然在处理HTTP错误(如400和 500代码)时效果很棒,但对于非HTTP错误(例如CORS错误)似乎会一直处于加载状态,例如:

tokenRequest = rxResource({
    params: () => this.loginRequested(),
    stream: ({params}) => {
      if (params == false) {
        return of(null);
      }
      return this.authService.requestLinkLogin()
        .pipe(
          catchError(err => {
            if (err.status == 0) {
              return throwError(() => new Error('Network error occurred'));
            }
            // other errors, just rethrow
            return throwError(() => err);
          })
        );
    }
  })

我的模板如下:

@let loginLoading = tokenRequest.isLoading();
@let loginError = tokenRequest.error();
@let loginData = tokenRequest.value();

@if (loginData) {
  Login link has been sent!
} @else if (loginError) {
  Something went wrong while requesting the authentication token.
  Error: {{ loginError.message }}
} @else if (loginLoading) {
  Loading...
} @else {
  <trimmed for brevity>
}

我以为根据我的if/else块,我会看到错误块,但我的UI仍然停留在“加载中”,控制台中却显示如下:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/send-token. (Reason: CORS request did not succeed). Status code: (null).
ERROR Error: Resource is currently in an error state (see Error.cause for details): Network error occurred
    Angular 5
    GenerateToken_Template generate-token.html:3
Caused by: Error: Network error occurred
    stream generate-token.ts:27
    RxJS 5

我尝试直接访问 status() 并判断它是否处于错误状态,但那也只是处于加载中。

是否有办法在 rxResourceObservable 内部处理这个?

解决方案

错误在下方的GitHub问题中有记载。

错误:资源当前处于错误状态#62065

文档也已在此 PR 中更新。

const firstName = computed(() => {
  if (useResource.hasValue()) {
    // `hasValue` serves 2 purposes:
    // - It acts as type guard to strip `undefined` from the type
    // - If protects against reading a throwing `value` when the resource is in error state
    return userResource.value().firstName;
  }

  // fallback in case the resource value is `undefined` or if the resource is in error state
  return undefined;
});

根据评论,推荐的方法是在直接访问值之前,先用 hasValue() 来检查该值是否存在,再通过 (value()) 访问。

在发生CORS错误(或其他任何错误状态)时,当你直接访问它时,会看到如下错误信息,并且处于错误状态。

[email protected]:26错误ResourceValueError:资源当前处于错误状态(详见Error.cause以获取详细信息):在解析期间的HTTP失败,针对 https://angular21base-gfnc--4200--4c73681d.local-credentialless.webcontainer.io/test/asdf 位于AppComponent_Template (app.component.html:2:40)

@let loginLoading = tokenRequest.isLoading(); 
@let loginError =
tokenRequest.error(); 
 <!-- check for value before accessing it -->
@let loginData = (tokenRequest.hasValue() ? tokenRequest.value() : null); <!-- <- changed here -->
@if (loginData) {
   Login link has been sent! 
  }
@else if (loginError) { 
  Something went wrong while requesting the authentication
token. Error: {{ loginError.message }}
} @else if (loginLoading) { 
  Loading... 
} @else { 
  asdfasdfasdf 
}

你也可以把逻辑写成:

@let loginLoading = tokenRequest.isLoading(); 
@let loginError =
tokenRequest.error(); 
 <!-- check for value before accessing it -->
@if (tokenRequest.hasValue()) {     <!-- changed here -->
  @let loginData = tokenRequest.value(); 
  Login link has been sent! 
} @else if (loginError) { 
  Something went wrong while requesting the authentication
token. Error: {{ loginError.message }}
} @else if (loginLoading) { 
  Loading... 
} @else { 
  asdfasdfasdf 
}

Stackblitz演示

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章