2017-08-13 102 views
2

假設這個角2段:如何在RxJS/Angular的兩個不同點上捕獲錯誤?

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回調傳遞給subscribe當請求成功不被調用就好了,但傳遞給catch回調沒有。

我試過在兩個不同的代碼部分負責處理錯誤。我希望在ApiService.request上拋出的錯誤信息最終會在第二次回調中結束,這樣我可以進一步優化對用戶的響應。我已經嘗試了throw errMsg和返回Observable.throw(errMsg)

爲什麼我使用.share()作爲observable的原因是因爲我不希望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

在你不需要再寫捕捉組件代碼, subscribe帶有三個函數作爲參數

subscribe(onSuccess, onError, onComplete); 

文檔:https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts (檢查例3)

+0

是否限定的onError有捕捉的第二時間的相同的效果? –

+1

沒有得到第二次捕捉你的意思。它所做的是:當發生錯誤時,不執行'onSuccess'函數,而是執行'onError'函數。這是正確的做法。如果我們想要捕獲異常並更改流中返回的內容,我們使用'catch'。通常在服務級別完成,而不是在組件中完成。 – Skeptor

+0

當我們不使用'subscribe',而是直接在HTML中使用'async'時,我們在組件中使用'catch'。這是不同的故事 – Skeptor