Permalink
Browse files

fix(http-client): call trackRequestEnd when fetch fails

  • Loading branch information...
ben-girardet committed Jan 16, 2019
1 parent 990e32d commit cf6498923467ac9dcb04acb5adb135b7dfd7ad0b
Showing with 62 additions and 21 deletions.
  1. +29 −21 src/http-client.ts
  2. +33 −0 test/http-client.spec.ts
@@ -123,29 +123,37 @@ export class HttpClient {
trackRequestStart(this);

let request = this.buildRequest(input, init);
return processRequest(request, this.interceptors, this)
.then(result => {
let response = null;

if (Response.prototype.isPrototypeOf(result)) {
response = Promise.resolve(result);
} else if (Request.prototype.isPrototypeOf(result)) {
request = result;
response = fetch(result);
} else {
// tslint:disable-next-line:max-line-length
throw new Error(`An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [${result}]`);
}

return processResponse(response, this.interceptors, request, this);
})
.then(result => {
if (Request.prototype.isPrototypeOf(result)) {
return this.fetch(result);
}
return processRequest(request, this.interceptors, this).then(result => {
let response = null;

if (Response.prototype.isPrototypeOf(result)) {
response = Promise.resolve(result);
} else if (Request.prototype.isPrototypeOf(result)) {
request = result;
response = fetch(result);
} else {
// tslint:disable-next-line:max-line-length
throw new Error(`An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [${result}]`);
}

return processResponse(response, this.interceptors, request, this);
})
.then(result => {
if (Request.prototype.isPrototypeOf(result)) {
return this.fetch(result);
}
return result;
})
.then(
result => {
trackRequestEnd(this);
return result;
});
},
error => {
trackRequestEnd(this);
throw error;
}
);
}

buildRequest(input: string | Request, init: RequestInit): Request {
@@ -1094,6 +1094,39 @@ describe('HttpClient', () => {
done.fail('fetch did error');
});
});
it('forward requests', (done) => {
const path = 'retry';
let retry = 3;
fetch.and.returnValue(Promise.reject(new Response(null, { status: 500 })));
let interceptor: Interceptor = {
response(r) { return r; },
responseError(r) {
if (retry--) {
let request = client.buildRequest(path);
return request;
} else {
throw r;
}
}
};
spyOn(interceptor, 'response').and.callThrough();
spyOn(interceptor, 'responseError').and.callThrough();

client.interceptors.push(interceptor);

// add check before fetch, this one passes.
expect(client.isRequesting).toBe(false);

client.fetch(path)
.catch(() => {
expect(interceptor.response).not.toHaveBeenCalled();
expect(interceptor.responseError).toHaveBeenCalledWith(jasmine.any(Response), jasmine.any(Request), client);
expect(fetch).toHaveBeenCalledTimes(4);
expect(client.activeRequestCount).toBe(0);
expect(client.isRequesting).toBe(false);
done();
});
});
});
});

0 comments on commit cf64989

Please sign in to comment.