typescript - Angular2 : การจัดการข้อผิดพลาด HTTP
ฉันกำลังพยายามจำลองพฤติกรรมต่อไปนี้ที่ฉันสามารถใช้งานได้สำเร็จโดยใช้ตัวดักจับ (interceptors) และคำสัญญา (promises) ใน Angular 1.x ในแอป Ionic2 ที่ใช้ Angular2:
- ดักจับข้อผิดพลาดของคำขอ HTTP
ถ้ารหัสสถานะคือ 401, แล้ว
a. ทำการขอลงทะเบียนลูกค้าอีกครั้ง ซึ่งจะให้โทเค็นบางอย่างที่ฉันสามารถแนบไปกับแต่ละคำขอในภายหลัง
b. ลองส่งคำขอเดิมอีกครั้งและให้ผลลัพธ์แก่ผู้เรียกผ่าน promise/observable
ถ้าสถานะข้อผิดพลาดเป็นค่าอื่นที่ไม่ใช่ 401 ให้ปล่อยให้โฟลว์ทำงานปกติต่อไปยังผู้เรียก
หมายเหตุ: กระบวนการลงทะเบียนไม่จำเป็นต้องมีการแทรกแซงจากผู้ใช้ (ไม่ต้องเข้าสู่ระบบ) ดังนั้นผมต้องการให้มันโปร่งใสต่อผู้ใช้โดยสมบูรณ์ ผมลงทะเบียนเพียงครั้งเดียวเมื่อแอปถูกโหลดครั้งแรก แต่เซสชันจะหมดอายุในที่สุดและผมจำเป็นต้องลงทะเบียนใหม่โดยอัตโนมัติ
นี่คือการใช้งาน Angular 1 ดั้งเดิม (ฉันรวมเฉพาะส่วน responseError ของตัวดักจับ):
responseError : function(rejection){
if(rejection.status == 401){
$log.info('Intercepting unauthorized 401 response. Will try to re-register the session and retry the request.');
var security = $injector.get('SecurityService');
var $http = $injector.get('$http');
return security.registerSession().then(function(){
return $http(rejection.config);
});
}else{
return rejection;
}
}
ตอนนี้ ฉันได้ห่อหุ้มบริการ HTTP ของ Angular2 แล้ว และฉันสามารถทำสิ่งง่ายๆ เช่น การเพิ่มหัวข้อไปยังแต่ละคำขอได้ อย่างไรก็ตามฉันกำลังประสบปัญหาในการสร้างพฤติกรรมเดียวกันโดยใช้ Angular2 และ Observables
ความพยายามของฉันจนถึงตอนนี้ นี่คือวิธีการร้องขอของ HTTP wrapper ของฉันที่บริการของฉันจะเรียกใช้งาน:
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
let req: Request = this.buildRequest(url, options);
this.beforeCall(req);
var observable = this.http
.request(req)
.retry(3)
.catch(res => {
debugger;
console.log("ERROR! " + res.status);
if(res.status == 401){
this.logger.log('Unauthorized request. Trying to register the session and then retry the request.');
return this.securityService.registerSession().subscribe(() => {
// What to do here so the client gets the result of the original request ??
});
}
})
.do((res:Response) => { this.afterCall(req, res) });
return observable;
}
คำตอบ #1
คุณสามารถดำเนินการขออีกครั้งหลังจากเริ่มเซสชันโดยใช้ตัวดำเนินการ flatMap ของ observables:
var observable = this.http
.request(req)
.retry(3)
.catch(res => {
debugger;
console.log("ERROR! " + res.status);
if(res.status == 401){
this.logger.log('Unauthorized request. Trying to register the session and then retry the request.');
return this.securityService.registerSession().flatMap(() => {
return this.http.request(req); // <--------
});
}
})
.do((res:Response) => { this.afterCall(req, res) });
return observable;
}
