Skip to content

Commit

Permalink
fix: re-throw original exception and preserve message in compute clie…
Browse files Browse the repository at this point in the history
…nt (#668)
  • Loading branch information
JustinBeckwith authored Apr 12, 2019
1 parent b11841e commit dffd1cc
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 50 deletions.
48 changes: 18 additions & 30 deletions src/auth/computeclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class Compute extends OAuth2Client {
data = await gcpMetadata.instance(tokenPath);
} catch (e) {
e.message = `Could not refresh access token: ${e.message}`;
this.wrapError(e);
throw e;
}
const tokens = data as Credentials;
Expand All @@ -82,36 +83,23 @@ export class Compute extends OAuth2Client {
return {tokens, res: null};
}

protected requestAsync<T>(opts: GaxiosOptions, retry = false):
GaxiosPromise<T> {
return super.requestAsync<T>(opts, retry).catch(e => {
const res = (e as GaxiosError).response;
if (res && res.status) {
let helpfulMessage = null;
if (res.status === 403) {
helpfulMessage =
'A Forbidden error was returned while attempting to retrieve an access ' +
'token for the Compute Engine built-in service account. This may be because the Compute ' +
'Engine instance does not have the correct permission scopes specified.';
} else if (res.status === 404) {
helpfulMessage =
'A Not Found error was returned while attempting to retrieve an access' +
'token for the Compute Engine built-in service account. This may be because the Compute ' +
'Engine instance does not have any permission scopes specified.';
}
if (helpfulMessage) {
if (e && e.message && !retry) {
helpfulMessage += ' ' + e.message;
}
if (e) {
e.message = helpfulMessage;
} else {
e = new Error(helpfulMessage);
(e as NodeJS.ErrnoException).code = res.status.toString();
}
}
protected wrapError(e: GaxiosError) {
const res = e.response;
if (res && res.status) {
e.code = res.status.toString();
if (res.status === 403) {
e.message =
'A Forbidden error was returned while attempting to retrieve an access ' +
'token for the Compute Engine built-in service account. This may be because the Compute ' +
'Engine instance does not have the correct permission scopes specified: ' +
e.message;
} else if (res.status === 404) {
e.message =
'A Not Found error was returned while attempting to retrieve an access' +
'token for the Compute Engine built-in service account. This may be because the Compute ' +
'Engine instance does not have any permission scopes specified: ' +
e.message;
}
throw e;
});
}
}
}
24 changes: 4 additions & 20 deletions test/test.compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ function mockExample() {
}

// set up compute client.
let sandbox: sinon.SinonSandbox;
const sandbox = sinon.createSandbox();
let compute: Compute;
beforeEach(() => {
compute = new Compute();
sandbox = sinon.createSandbox();
});

afterEach(() => {
Expand Down Expand Up @@ -129,37 +128,22 @@ it('should return false for createScopedRequired', () => {
});

it('should return a helpful message on request response.statusCode 403', async () => {
// Mock the credentials object. Make sure there's no expiry_date set.
compute.credentials = {refresh_token: 'hello', access_token: 'goodbye'};

const scopes = [
nock(url).get('/').reply(403), nock(HOST_ADDRESS).get(tokenPath).reply(403)
];

const scope = mockToken(403);
const expected = new RegExp(
'A Forbidden error was returned while attempting to retrieve an access ' +
'token for the Compute Engine built-in service account. This may be because the ' +
'Compute Engine instance does not have the correct permission scopes specified. ' +
'Could not refresh access token.');

await assertRejects(compute.request({url}), expected);
scopes.forEach(s => s.done());
scope.done();
});

it('should return a helpful message on request response.statusCode 404', async () => {
// Mock the credentials object.
compute.credentials = {
refresh_token: 'hello',
access_token: 'goodbye',
expiry_date: (new Date(9999, 1, 1)).getTime()
};
// Mock the request method to return a 404.
const scope = nock(url).get('/').reply(404);
const scope = mockToken(404);
const expected = new RegExp(
'A Not Found error was returned while attempting to retrieve an access' +
'token for the Compute Engine built-in service account. This may be because the ' +
'Compute Engine instance does not have any permission scopes specified.');

await assertRejects(compute.request({url}), expected);
scope.done();
});
Expand Down

0 comments on commit dffd1cc

Please sign in to comment.