TypeScript - איך אני תופס שגיאה בשני נקודות שונות ב-RxJS/Angular?
נניח את הקטע הקוד הזה ב-Angular 2:
export class ApiService {
// do stuff
request(...): Observable<Response> {
return this.http.request(...)
.share()
.catch((error: any) => {
let errMsg = 'my error';
// do more stuff...
// tried: throw errMsg;
// tried: return Observable.throw(errMsg);
});
}
}
אז :
api.request(...).catch(() => {
console.log('caught');
return Observable.from([]);
}).subscribe({
console.log('everything fine');
});
ה-next callback שעובר ל-subscribe אכן נקרא כשמבצעים את הבקשה בהצלחה, אבל ה-callback שעובר ל-catch לא נקרא.
ניסיתי להתמודד עם השגיאה בשני חלקים שונים בקוד שיש להם אחריות שונה. הייתי רוצה שהודעת השגיאה שתיזרק ב-ApiService.request תסתיים בקולבק השני כדי שאוכל לחדד עוד יותר את התגובה שלי למשתמש. ניסיתי גם throw errMsg וגם להחזיר Observable.throw(errMsg).
הסיבה לכך שאני משתמש ב-.share() עבור האובזרבל היא כי אני לא רוצה שלקוח ה-HTTP ייצר בקשה אחת עבור כל מנוי.
באיזה מקום אני טועה בזה?
עריכה:
הדוגמה שלי למעלה לא באמת תיארה את הבעיה שהייתה לי. קטע הקוד השני הזה מאפשר לשחזר אותה:
const a = Rx.Observable.create(function(observer){
observer.error('h');
}).share().catch(err=> {
console.error('first place',err);
throw 'err'
})
.subscribe(() => null)
.subscribe(console.log, console.error);
המנוי הראשון נכשל בלתפוס את השגיאה (בגלל שלא היה מוגדר מטפל בשגיאות) ושבר את השרשרת למנוי השני.
תשובה #1
ממה שהבנתי אתה רוצה לתפוס את השגיאה בשני מקומות. לפי התיעוד אתה צריך להשתמש ב-throw. ניסיתי וזה עובד לי בסדר. הנה קטע הקוד:
const a = Rx.Observable.create(function(observer){
observer.error('h');
});
a.catch(err=> {
console.error('first place',err);
throw 'err'
}).subscribe(console.log,console.error);
פלט
x first place
x err
JSBin : https://jsbin.com/jefalazibo/edit?html,js,console
בקוד של הרכיב אין צורך לכתוב עוד catch. subscribe לוקח שלוש פונקציות כארגומנטים
subscribe(onSuccess, onError, onComplete);
תיעוד: https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts (בדוק דוגמה 3)
