简体   繁体   中英

Angular2 custom request

I am using a custom HTTP request class for adding a Authorization Header to all of my requests, this works fine on almost every android device. Wired thing now is that I got some customer complaints that they are getting the 'No internet connection' error although they have a working network connection (other apps work and the errors are transmitted to the Sentry servers also). As I am using Sentry error tracking I found out that these customers are all getting the error because the timeout error is thrown after 10 seconds for the first request at app start. I guessed that something has to be wrong with this request so I built an alpha version for a limited number of users to track down the error (I send the options of every request to Sentry), but the requests look fine. Next guess was that something is wrong with cordova-plugin-nativestorage on these devices but as I am catching them it should at lease return an empty token. No clue how to fix it right now. Any advice is appreciated!

export class CustomRequest {
  apiToken: string = '';

  constructor(private http: Http) { }

  protected request(options: any): Observable<any> {

    // If Native Storage doens't find a token, return an empty
    let errorNativeStorage$ = function (): Observable<any> {
      return Observable.of({ Token: '' });
    };

    // Get Token form Native Storage
    let token$ = Observable.fromPromise(NativeStorage.getItem('JWT'))
      .catch(errorNativeStorage$);

    // Handle request errors
    let genericError$ = function (error: Response | any): Observable<any> {
      let errMsg: string;
      if (error instanceof Response) {
        const body = error.json() || '';
        const err = body.error || JSON.stringify(body);
        errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
      } else {
        errMsg = error.message ? error.message : error.toString();
      }

      console.error(errMsg);
      Raven.captureException(error, { extra: { errorMsg: errMsg } });

      return Observable.of({
        Errors: { General: 'No internet connection.' }
      });
    };

    // the request
    let request$ = (options) => {
      return this.http.request(new Request(options))
        .retryWhen(error => error.delay(1000))
        .timeout(10000, new Error('timeout'))
        .map((res: Response) => res.json())
        .catch(genericError$);
    };

    // get the token and build request
    return token$
      .map(jwt => {
        if (options.body) {
          if (typeof options.body !== 'string') {
            options.body = JSON.stringify(options.body);
          }
          options.body = options.body.replace(/ /g, '').replace(/\r?\n|\r/g,   '');
        }

        options.headers = new Headers({
          'Content-Type': 'application/x-www-form-urlencoded,      application/json'
        });

        if (jwt.Token) {
          options.headers.append('Authorization', `Bearer ${jwt.Token}`);
        }

        Raven.captureMessage('request options', { level: 'info',    environment: 'live', extra: options });
        return options;
      })
      .switchMap(options => request$(options));
  }
}

I am using:

  • Ionic 2.0.0-beta.11
  • Angular 2.0.0-rc.4
  • Most recent version of NativeStorage plugin from github

Devices with the error (only two examples, there are more):

  • Samsung SM-N910F (Webview: Chrome Mobile 53.0.2785, Android 6.0.1)
  • Samsung SM-G800F (Webview: Chrome Mobile 53.0.2785, Android 5.1.1)

If somebody's interested: The root cause was that people that upgraded Android somehow lost the chrome webview app and Angular was not working without one (of course). I solved it by packaging the crosswalk-webview in my app!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM