如何解决忽略可观察的请求错误
我有一个使用GraphQL作为API结构的Angular应用程序。当在后端引发错误时,请求的状态为500,但仍返回标准JSON(带有“错误”数组的ableit)。但是,当我仅订阅它时,此500状态会触发可观察的错误。我想忽略引发的错误,而只是检查响应上的错误数组。我的第一种方法:
login(email: string,password: string) {
this.loginGQL.watch({email,password}).valueChanges.subscribe(result => {
if(!result.errors || result.errors.length === 0) {
this.authData.next(result.data.login);
} else {
this.error.next(result.errors[0].message);
}
});
}
我已经尝试过这种方法来解决问题:
login(email: string,password: string) {
this.loginGQL.fetch({email,password}).pipe(map(result =>
result.data
),catchError(
err => {
console.log(err);
return err.message;
}
)).subscribe(
(finalResult: string | AuthData) => {
if(typeof finalResult !== "string") {
this.authData.next(finalResult);
} else {
console.log(finalResult);
this.error.next(finalResult);
}
}
);
}
但是,这不仅丢弃了响应,而且错误消息也以某种方式被拆分为单个字母。不是最好的体验。
对此最好的方法是什么?预先感谢。
解决方法
Observable.subscribe()
有几个处理错误情况的重载。 subscribe
方法最多使用3个参数(next
,error
,complete
)。我们可以利用第二个error
参数来处理拦截异常并根据需要对其进行处理。 More info
login(email: string,password: string) {
this.loginGQL.watch({email,password}).valueChanges.subscribe(result => {
this.authData.next(result.data.login);
},errorResult => {
if(errorResult.errors && errorResult.errors.length > 0) {
this.error.next(errorResult.errors[0].message);
}
});
}
请注意,我从if(!result.errors || result.errors.length === 0)
函数参数中删除了next
条件。如果调用next
或complete
函数,则不会引发任何错误。由于我更喜欢在代码中进行“健全性检查”以防止随机的空引用错误,因此我在error
函数中保留了条件的倒数。
我认为您可以尝试这样的事情:
src$.pipe(
catchError(err => {
// throwing another error so that `retryWhen` will intercept it
const sources = [throwError(err)];
// send the `errors` array as a `next` notification
err.status === 500 && sources.unshift(of(err.errors))
return concat(...sources);
}),// make sure the subscription is keept alive after `500` errors
retryWhen(errors => errors.pipe(filter(err => err.status === 500))),)
,
使用catchError
运算符是正确的,但是其中之一是必须必须返回一个可观察值。并且由于您要返回err.message
,因此字符串的每个字符都会单独发出。相反,您可以使用RxJS of()
函数以next
通知的形式返回错误。它会被发送到订阅的next
回调中。尝试以下
import { of } from 'rxjs';
import { map,catchError } from 'rxjs/operators';
login(email: string,password: string) {
this.loginGQL.fetch({ email,password }).pipe(
map(result => result.data),catchError(err => {
console.log(err);
return of(err); // <-- you could also return the required array here
})
).subscribe(
(finalResult: string | AuthData) => {
if (typeof finalResult !== "string") {
this.authData.next(finalResult);
} else {
console.log(finalResult);
this.error.next(finalResult);
}
}
);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。