ค้นหาเว็บไซต์

typescript - Angular2 : การจัดการข้อผิดพลาด HTTP


ฉันกำลังพยายามจำลองพฤติกรรมต่อไปนี้ที่ฉันสามารถใช้งานได้สำเร็จโดยใช้ตัวดักจับ (interceptors) และคำสัญญา (promises) ใน Angular 1.x ในแอป Ionic2 ที่ใช้ Angular2:

  1. ดักจับข้อผิดพลาดของคำขอ HTTP
  2. ถ้ารหัสสถานะคือ 401, แล้ว

    a. ทำการขอลงทะเบียนลูกค้าอีกครั้ง ซึ่งจะให้โทเค็นบางอย่างที่ฉันสามารถแนบไปกับแต่ละคำขอในภายหลัง

    b. ลองส่งคำขอเดิมอีกครั้งและให้ผลลัพธ์แก่ผู้เรียกผ่าน promise/observable

  3. ถ้าสถานะข้อผิดพลาดเป็นค่าอื่นที่ไม่ใช่ 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;
}

บทความที่เกี่ยวข้อง