Зачем обрабатывать ошибки с catchError, а не в обратном вызове ошибок подписки в Angular - PullRequest
0 голосов
/ 19 февраля 2019

Поэтому я обычно пишу свои http-запросы примерно так:

Сервис

getData(){
  return this.http.get('url')
}

Компонент

getTheData() {
  this.service.getData().subscribe(
    (res) => {
      //Do something
    }, 
    (err) => {
      console.log('getData has thrown and error of', err)
    })

Но, просматривая документацию Angular, они, похоже, форматируют ее в Сервисе

getHeroes(): Observable<Hero[]> {
  return this.http.get<Hero[]>(this.heroesUrl)
    .pipe(
      catchError(this.handleError('getHeroes', []))
    );
}

В чем неявный плюс, так как он мне кажется довольно многословным, и лично у меня никогда не было необходимости транслироватьмои ошибки.

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Все дело в разделении проблем.

Одним из основных преимуществ использования catchError является отделение всей логики поиска данных, включая все ошибки, которые могут возникнуть на пути от представления данных.

Пусть Компоненты должны заботиться только о представлении данных

Компоненты должны заботиться только о данных (есть они или нет).Они не должны заботиться о специфике того, как извлекать данные или обо всех вещах, которые могут работать неправильно во время извлечения данных.

Компоненты не должны извлекать или сохранять данные напрямую, и они, безусловно, не должнысознательно представлять поддельные данные.Они должны сосредоточиться на представлении данных и делегировать доступ к данным службе. [Угловое руководство]

Допустим, ваши данные представляют собой список элементов.Ваш Компонент вызовет функцию service.getItemList() и, поскольку он заботится только о данных, будет ожидать:

  • список, содержащий элементы
  • пустой список
  • нетто есть null или undefined

Вы можете легко обработать все эти случаи с помощью ngIf в шаблоне компонента и отобразить данные или что-то еще в зависимости от случая.Наличие функции Service, возвращающей «чистый» Observable, который возвращает только данные (или null) и не должен вызывать каких-либо ошибок, делает код в ваших компонентах простым, поскольку вы можете легко использовать AsyncPipe вшаблон для подписки.

Не позволяйте компонентам заботиться о таких особенностях извлечения данных, как ошибки

Ваша логика поиска и обработки ошибок может со временем изменяться.Возможно, вы переходите на новый Api и вдруг столкнетесь с различными ошибками.Не позволяйте вашим компонентам беспокоиться об этом.Переместите эту логику в службу.

Удаление доступа к данным из компонентов означает, что вы можете в любое время изменить свое решение о реализации, не касаясь каких-либо компонентов.Они не знают, как работает сервис. [Angular tutorial]

Поместите логику поиска данных и обработки ошибок в Сервис

Обработка ошибок является частью вашей логики поиска данных, а не частью вашейлогика представления данных.

В вашей Службе поиска данных вы можете подробно обработать ошибку с помощью оператора catchError.Может быть, есть некоторые вещи, которые вы хотите сделать для всех ошибок, таких как:

  • log it
  • отображение ориентированного на пользователя сообщения об ошибке в качестве уведомления (см. Показать сообщения )
  • извлечение альтернативных данных или возврат значения по умолчанию

Перемещение части этого в функцию this.handleError('getHeroes', []) предотвращает дублирование кода.

После сообщения об ошибке консоли, обработчик создает удобное для пользователя сообщение и возвращает безопасное значение приложению, чтобы оно могло продолжать работать. [Angular tutorial]

Может также наступить время, когда вам нужно будет вызвать существующую сервисную функцию из нового Компонента.Наличие вашей логики обработки ошибок в функции Service делает это простым, поскольку вам не придется беспокоиться об обработке ошибок при вызове функции из нового компонента.

Таким образом, все сводится к разделению логики поиска данных (вСлужбы) из вашей логики представления данных (в компонентах) и простоты расширения вашего приложения в будущем.

0 голосов
/ 23 июля 2019

Просто наткнулся на это и подумал, что я обновлю свои выводы, чтобы лучше ответить на свой вопрос.

Хотя основной смысл абстрагирования логики обработки ошибок от компонента является полностью допустимой и одной из основных, существует несколько других причин, по которым catchError используется вместо простой обработки ошибки с ошибкой подписки.method.

Основная причина заключается в том, что catchError позволяет обрабатывать возвращаемую наблюдаемую либо из http.get, либо из первого оператора, который выдает ошибки в методе канала, т.е.

this.http.get('url').pipe(filter(condition => condition = true), map(filteredCondtion => filteredCondition = true), catchError(err, return throwError(err)).subscribe(......)

Таким образом, если какой-либо из этих операторов по какой-либо причине завершится сбоем, то catchError поймает наблюдаемую ошибку, возвращаемую из этого, но главное преимущество, с которым я столкнулся при использовании catchError, заключается в том, что он может предотвратить закрытие наблюдаемого потока всобытие ошибки.

Использование throwError или catchError(err throw 'error occcured') вызовет ошибочную часть метода подписки, закрывая тем самым наблюдаемый поток, однако используя catchError, как это сделано;

Пример первый - catchError(err, of({key:'streamWontError'}) // Вернет наблюдаемую, объявленную как, и, следовательно, выдает необходимость вызвать ошибку при подписке

Пример два - catchError(err, catchedObservable} // Это на самом деле попытаетсяснова вызвать сбойную наблюдаемую в случае ошибки, таким образом снова предотвращая вызов метода ошибки.

0 голосов
/ 19 февраля 2019

По данным команды Angular«Метод handleError () сообщает об ошибке, а затем возвращает безобидный результат, чтобы приложение продолжало работать»

Поскольку каждый метод службы возвращает различный вид наблюдаемого результата, функция в catchError, например handleError (), здесь принимает параметр типа, поэтому он может возвращать безопасное значение в качестве типа, ожидаемого приложением.

...