遇到非HTTP错误时,rxResource会一直处于加载状态
我正在尝试使用Angular的 rxResource 来处理HTTP请求,主要是为了在显示上获得更好的易用性,利用 rxResource 的 hasValue()、error 和 isLoading()。
虽然在处理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() 并判断它是否处于错误状态,但那也只是处于加载中。
是否有办法在 rxResource 或 Observable 内部处理这个?
解决方案
错误在下方的GitHub问题中有记载。
文档也已在此 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。