Я провел довольно много исследований, прежде чем решил опубликовать вопросы здесь. Мои знания о том, как Angular (или вообще) обрабатывает ошибку HTTP, очень туманны, поэтому я ищу некоторые разъяснения/предложения.
Для простоты предположим, что у меня есть API для отдыха GET http://example.com
, который случайным образом возвращает {error: 'Error message'}
или {data: 'Data is available'}
, где error
указывает на то, что что-то пошло не так (запрос выполнен успешно, но есть какая-то внутренняя ошибка), а data
указывает на то, что все работает нормально.
Теперь, есть 2 вещи, которые, насколько я понимаю, нуждаются в обработке. Первое — это обработка при сбое запроса, например, сетевая ошибка, блокировка 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
});
Я также прочитал другое предложение использовать catch()
для subscribe()
, но 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()
, но я не совсем уверен, в чем их разница (например, catchError()
в service.ts
и error
из subscribe(success, error)
в app.ts
.