如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是啥[重复]
Posted
技术标签:
【中文标题】如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是啥[重复]【英文标题】:How to throwError properly and what are the meaning of different error catchers in Angular HTTP [duplicate]如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是什么[重复] 【发布时间】:2020-08-21 01:03:33 【问题描述】:在决定在这里发布问题之前,我做了很多研究。我对 Angular(或一般)如何处理 HTTP 错误的了解非常模糊,因此我正在寻找一些澄清/建议。
为简单起见,假设我有一个休息 API GET http://example.com
,它将随机返回 error: 'Error message'
或 data: 'Data is available'
,其中 error
表示出现问题(请求成功完成,但存在一些内部错误) data
表示一切正常。
现在,据我了解,有两件事需要处理。第一件事是请求失败时的处理,例如网络错误、被CORS阻塞等,第二件事是处理成功的请求,但看是error
还是data
。
TL;DR:如何将下面的 jQuery 转换为 Angular?
通常,使用 jQuery,我会这样做:
$.get('http://example.com').done(data =>
if ('error' in data) console.log('Request completed, but there is an error in the remote server');
else console.log('Everything completed successfully');
).fail(error =>
console.log('Error while requesting data', error);
);
现在在 Angular 中,事情变得复杂了,无论我尝试什么,我似乎都无法抛出错误(所有函数都已正确导入):
//service.ts
getStatus()
return this.http.get('https://test.com/')
.pipe(
map(data =>
if ('error' in data)
//I would like to throw an error that can be caught at subscribe(done, error) later
//But this rxjs won't throw anything, subscribe() will still resolve with done()
return throwError('Request completed, but there is an error in the remote server');
return data;
),
tap(data =>
//Process the data, should not be called if map() throwError()?
,
catchError(error =>
//I assume this is where the HTTP request failed due to network, CORS, etc.
return throwError('Error while requesting data');
)
);
//app.ts
this.service.getStatus().subscribe(data =>
//I expect this function to be called ONLY if there was no throwError(), but that wasn't the case
//No matter what I try in `service.ts`, this will always be called
, (error) =>
//I expect this to call when throwError() is called from `service.ts` but it never happens
);
我还阅读了另一个关于在 subscribe()
上使用 catch()
的建议,但 catch()
从来都不是订阅上的方法:
//app.ts
this.service.getStatus().subscribe(data =>
//I expect this function to be called ONLY if there was no throwError(), but that wasn't the case
//No matter what I try in `service.ts`, this will always be called
).catch(error =>
//This is not valid
);
我尝试过的都没有奏效,管道中有多个地方我可以throwError()
,但我不太确定它们的区别是什么(例如,service.ts
中的catchError()
和error
来自subscribe(success, error)
在app.ts
。
【问题讨论】:
这实际上会像我预期的那样抛出错误!你能把它作为一个答案,以便我能以某种方式接受它吗? 【参考方案1】:对我来说似乎有点复杂。如果您不想实现 http 拦截器,我会简单地做这样的事情
//service.ts
getStatus()
return this.http.get('http://www.test.com');
然后
//app.ts
this.testService.getStatus()
.subscribe(data =>
if ('error' in data)
// process Error
return;
// process data
console.log(data);
, error =>
// http error
console.log(error);
);
对于 tap 操作符,它用于执行您想要的任何涉及数据或不涉及数据的操作(例如日志记录),但它始终会返回与其源相同的 observable。
【讨论】:
哇。这比我想象的要简单。我可能想多了。即使http()返回错误,tap()也会被激活吗? 不,如果返回一些数据就会触发。以上是关于如何正确抛出错误以及Angular HTTP中不同错误捕获器的含义是啥[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Angular 4:如何正确处理应用程序级别的 http 错误作为 Observable 错误?
http.put 在使用 Chrome 但不是 IE 的 Angular 2 / Web API 中抛出错误
如何解决 Angular 单元测试错误:“在 afterAll\n[object ErrorEvent] 中抛出了一个错误”