Skip to content
This repository has been archived by the owner on Jun 24, 2024. It is now read-only.

Commit

Permalink
fix: retry on failure and throw correct errors
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalsadhu committed Dec 4, 2017
1 parent 16ace78 commit 3275ec6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 9 deletions.
45 changes: 38 additions & 7 deletions lib/sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const assert = require('assert');
const VError = require('verror');
const mime = require('mime-types');
const { dirname, extname } = require('path');
const pRetry = require('p-retry');
const Boom = require('boom');

/**
* Check and wrap an assumed error object.
Expand Down Expand Up @@ -178,8 +180,26 @@ module.exports = class SinkGCS extends EventEmitter {

async get(fileName) {
await this[ready];
const data = await this[getGcsFile](fileName).download();
return data.toString();
const file = this[getGcsFile](fileName);
if (!await file.exists()) {
throw Boom.notFound(`Unable to find requested file "${fileName}"`, {
file: fileName,
});
}

try {
return await pRetry(() => file.download(), { retries: 3 });
} catch (err) {
throw Boom.serverUnavailable(
`File "${
fileName
}" exists, however multiple attempts to download the file from google cloud storage has failed.`,
{
file: fileName,
description: err.message,
}
);
}
}

async set(fileName, fileContent) {
Expand All @@ -203,11 +223,22 @@ module.exports = class SinkGCS extends EventEmitter {
);

await this[ready];
await this[getGcsFile](fileName).save(fileContent, {
metadata: {
contentType,
},
});
const file = this[getGcsFile](fileName);
const saveFile = () =>
file.save(fileContent, { metadata: { contentType } });
try {
return await pRetry(saveFile, { retries: 3 });
} catch (err) {
throw Boom.serverUnavailable(
`Unable to save file "${
fileName
}" to google cloud storage. 3 attempts failed.`,
{
file: fileName,
description: err.message,
}
);
}
}

async has(fileName) {
Expand Down
19 changes: 19 additions & 0 deletions test/__snapshots__/sink.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`.get() - should reject when file does not exists 1`] = `
"{
\\"data\\": {
\\"file\\": \\"some-file\\"
},
\\"isBoom\\": true,
\\"isServer\\": false,
\\"output\\": {
\\"statusCode\\": 404,
\\"payload\\": {
\\"statusCode\\": 404,
\\"error\\": \\"Not Found\\",
\\"message\\": \\"Unable to find requested file \\\\\\"some-file\\\\\\"\\"
},
\\"headers\\": {}
}
}"
`;

exports[`.set() - should error if file extension cannot be resolved to a mime type 1`] = `"Expected file extension for argument \\"fileName\\" to resolve to a valid mime type. Instead extension \\".fake\\" resolved to content type \\"false\\""`;

exports[`.writer() - bad extension for "type" argument - should throw 1`] = `"Expected type \\"asdasd.fake\\" to resolve to a valid mime type, instead got \\"false\\""`;
Expand Down
23 changes: 21 additions & 2 deletions test/sink.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,13 @@ test('.writer() - happy path', async done => {
});
});

test('.get() - should resolve fileContent when file exist', async () => {
test('.get() - should resolve fileContent when file exists', async () => {
expect.hasAssertions();
const sink = getValidSink();

const content = 'some-file-content';
sink.gcs._setState({
exists: true,
download: {
'some-file': content,
},
Expand All @@ -108,17 +110,34 @@ test('.get() - should resolve fileContent when file exist', async () => {
expect(result).toBe(content);
});

test('.get() - should reject when file does not exists', async () => {
expect.hasAssertions();
const sink = getValidSink();

sink.gcs._setState({
exists: false,
});

try {
await sink.get('some-file');
} catch (err) {
expect(JSON.stringify(err, null, 2)).toMatchSnapshot();
}
});

test('.set() - should return no value/undefined if success', async () => {
expect.hasAssertions();
const sink = getValidSink();

sink.gcs._setState({ save: '' });

const result = await sink.set('some-file.json', 'file-content');

expect(result).toBe(undefined);
expect(result).toBe('');
});

test('.set() - should error if file extension cannot be resolved to a mime type', async () => {
expect.hasAssertions();
const sink = getValidSink();

try {
Expand Down

0 comments on commit 3275ec6

Please sign in to comment.