Skip to content

Commit 9b42b58

Browse files
committed
Add custom error handling for github module
1 parent 61ece07 commit 9b42b58

File tree

11 files changed

+146
-66
lines changed

11 files changed

+146
-66
lines changed

constants/index.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

definitions/constants.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
exports.fileTypes = {
2+
MARKDOWN_NOTE: 'MARKDOWN_NOTE',
3+
SNIPPET_NOTE: 'SNIPPET_NOTE',
4+
MULTIMEDIA: 'MULTIMEDIA',
5+
RAW_CSON: 'RAW_CSON',
6+
UNKNOWN: 'UNKNOWN'
7+
};
8+
9+
exports.events = {
10+
FILE_CREATE_OR_UPDATE: 'FILE_CREATE_OR_UPDATE',
11+
FILE_DELETE: 'FILE_DELETE',
12+
FILE_CHANGE: 'FILE_CHANGE'
13+
};

definitions/errors.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class BaseError extends Error {
2+
constructor(...args) {
3+
super(...args);
4+
this.stack = `${this.message}\n${new Error().stack}`;
5+
}
6+
}
7+
8+
exports.FileSystemError = class FileSystemError extends BaseError {
9+
constructor(...args) {
10+
super(...args);
11+
this.code = 'FILE_SYSTEM_ERROR';
12+
this.name = 'FileSystemError';
13+
}
14+
};
15+
16+
exports.ValidationError = class ValidationError extends BaseError {
17+
constructor(...args) {
18+
super(...args);
19+
this.code = 'VALIDATION_ERROR';
20+
this.name = 'ValidationError';
21+
}
22+
};
23+
24+
exports.QueueError = class QueueError extends BaseError {
25+
constructor(...args) {
26+
super(...args);
27+
this.code = 'QUEUE_ERROR';
28+
this.name = 'QueueError';
29+
}
30+
};

definitions/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const constants = require('./constants');
2+
const errors = require('./errors');
3+
4+
module.exports = class definitions {
5+
constructor() {
6+
this.constants = constants;
7+
this.errors = errors;
8+
}
9+
};

github/client/index.js renamed to github/client.js

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,22 @@
66
const requestFn = require('request');
77
const { resolve } = require('url');
88
const { promisify } = require('util');
9-
const httpStatus = require('../httpStatus');
10-
const errorCode = require('./errors');
9+
const httpStatus = require('./httpStatus');
10+
const {
11+
RepositoryEmptyError,
12+
GitHubInternalError,
13+
AuthorizationError
14+
} = require('./errors');
15+
1116
const {
1217
trimSlashes,
1318
decodeToUtf8
14-
} = require('../helpers');
19+
} = require('./helpers');
1520

1621
const GITHUB_BLOB_MODE = '100644';
1722
const GITHUB_BLOB_TYPE = 'blob';
18-
const ERR_FILE_NOT_FOUND = 'ENOENT';
1923

20-
exports.constants = { GITHUB_BLOB_MODE, GITHUB_BLOB_TYPE, ERR_FILE_NOT_FOUND };
21-
exports.errorCode = errorCode;
24+
exports.constants = { GITHUB_BLOB_MODE, GITHUB_BLOB_TYPE };
2225

2326
exports.Client = class GithubClient {
2427
/**
@@ -75,6 +78,19 @@ exports.Client = class GithubClient {
7578
return this.userId;
7679
}
7780

81+
/**
82+
* Generate an error object based on the status code
83+
* @param {number} statusCode
84+
* @returns {Error}
85+
*/
86+
static generateError(statusCode) {
87+
return (message) => {
88+
if (statusCode === httpStatus.UNAUTHORIZED) return new AuthorizationError(message);
89+
if (statusCode === httpStatus.CONFLICT) return new RepositoryEmptyError(message);
90+
return new GitHubInternalError(message);
91+
};
92+
}
93+
7894
/**
7995
* Get github user id
8096
* @returns {void}
@@ -86,8 +102,7 @@ exports.Client = class GithubClient {
86102
});
87103

88104
if (status !== httpStatus.OK) {
89-
this.logger.error(body);
90-
throw new Error('Failed to fetch user details');
105+
throw GithubClient.generateError(status)(`Failed to fetch user details: ${body.message}`);
91106
}
92107

93108
const { login } = body;
@@ -106,15 +121,8 @@ exports.Client = class GithubClient {
106121
path: `/repos/${this.userId}/${this.repoConfig.name}/git/refs/${refs}` // default notes branch is 'master'
107122
});
108123

109-
if (status === httpStatus.CONFLICT) {
110-
const error = new Error(body.message);
111-
error.code = errorCode.ERR_REPOSITORY_EMPTY;
112-
throw error;
113-
}
114-
115124
if (status !== httpStatus.OK) {
116-
this.logger.error(body);
117-
throw new Error('Failed to fetch head');
125+
throw GithubClient.generateError(status)(`Failed to fetch head: ${body.message}`);
118126
}
119127

120128
const { object } = body;
@@ -133,8 +141,7 @@ exports.Client = class GithubClient {
133141
});
134142

135143
if (status !== httpStatus.OK) {
136-
this.logger.error(body);
137-
throw new Error('Failed to fetch commit stats');
144+
throw GithubClient.generateError(status)(`Failed to fetch commit stats: ${body.message}`);
138145
}
139146

140147
const { message, tree } = body;
@@ -156,8 +163,7 @@ exports.Client = class GithubClient {
156163
body: { content, encoding }
157164
});
158165
if (status !== httpStatus.CREATED) {
159-
this.logger.error(body);
160-
throw new Error('Failed to create blob from content');
166+
throw GithubClient.generateError(status)(`Failed to create blob from content: ${body.message}`);
161167
}
162168

163169
const { sha } = body;
@@ -170,8 +176,7 @@ exports.Client = class GithubClient {
170176
path: `/repos/${this.userId}/${this.repoConfig.name}/git/blobs/${blobSHA}`
171177
});
172178
if (status !== httpStatus.OK) {
173-
this.logger.error(body);
174-
throw new Error(`Failed to get blob ${blobSHA}`);
179+
throw GithubClient.generateError(status)(`Failed to get blob ${blobSHA}: ${body.message}`);
175180
}
176181

177182
const { content, encoding } = body;
@@ -201,8 +206,7 @@ exports.Client = class GithubClient {
201206
}
202207

203208
if (status !== httpStatus.OK) {
204-
this.logger.error(body);
205-
throw new Error(`Failed to get tree ${treeHash}`);
209+
throw GithubClient.generateError(status)(`Failed to get tree ${treeHash}: ${body.message}`);
206210
}
207211
const { tree, truncated } = body;
208212
return { tree, truncated };
@@ -233,8 +237,7 @@ exports.Client = class GithubClient {
233237
});
234238

235239
if (status !== httpStatus.CREATED) {
236-
this.logger.error(body);
237-
throw new Error('Failed to update tree');
240+
throw GithubClient.generateError(status)(`Failed to update tree: ${body.message}`);
238241
}
239242
return body.sha;
240243
}
@@ -252,8 +255,7 @@ exports.Client = class GithubClient {
252255
});
253256

254257
if (status !== httpStatus.CREATED) {
255-
this.logger.error(body);
256-
throw new Error('Failed to update tree');
258+
throw GithubClient.generateError(status)(`Failed to update tree: ${body.message}`);
257259
}
258260
return body.sha;
259261
}
@@ -283,8 +285,7 @@ exports.Client = class GithubClient {
283285
});
284286

285287
if (status !== httpStatus.CREATED) {
286-
this.logger.error(body);
287-
throw new Error('Failed to commit file');
288+
throw GithubClient.generateError(status)(`Failed to commit file: ${body.message}`);
288289
}
289290
return body.sha;
290291
}
@@ -305,8 +306,7 @@ exports.Client = class GithubClient {
305306
});
306307

307308
if (status !== httpStatus.OK) {
308-
this.logger.error(body);
309-
throw new Error('Failed to update head');
309+
throw GithubClient.generateError(status)(`Failed to update head: ${body.message}`);
310310
}
311311
return body;
312312
}
@@ -330,8 +330,7 @@ exports.Client = class GithubClient {
330330
});
331331

332332
if (status !== httpStatus.CREATED) {
333-
this.logger.error(body.message);
334-
throw new Error('Failed to initialize repository');
333+
throw GithubClient.generateError(status)(`Failed to initialize repository: ${body.message}`);
335334
}
336335

337336
const { commit } = body;

github/client/errors.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

github/errors.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
exports.RepositoryEmptyError = class RepositoryEmptyError extends Error {
2+
constructor(...args) {
3+
super(...args);
4+
this.code = 'ERR_REPOSITORY_EMPTY';
5+
this.name = 'RepositoryEmptyError';
6+
this.stack = `${this.message}\n${new Error().stack}`;
7+
}
8+
};
9+
10+
exports.AuthorizationError = class AuthorizationError extends Error {
11+
constructor(...args) {
12+
super(...args);
13+
this.code = 'ERR_AUTHORIZATION';
14+
this.name = 'AuthorizationError';
15+
this.stack = `${this.message}\n${new Error().stack}`;
16+
}
17+
};
18+
19+
exports.ConnectionError = class ConnectionError extends Error {
20+
constructor(...args) {
21+
super(...args);
22+
this.code = 'ERR_CONNECTION';
23+
this.name = 'ConnectionError';
24+
this.stack = `${this.message}\n${new Error().stack}`;
25+
}
26+
};
27+
28+
exports.RemoteFileNotFoundError = class RemoteFileNotFoundError extends Error {
29+
constructor(...args) {
30+
super(...args);
31+
this.code = 'ERR_REMOTE_FILE_NOT_FOUND';
32+
this.name = 'RemoteFileNotFoundError';
33+
this.stack = `${this.message}\n${new Error().stack}`;
34+
}
35+
};
36+
37+
exports.GitHubInternalError = class GitHubError extends Error {
38+
constructor(...args) {
39+
super(...args);
40+
this.code = 'ERR_GITHUB_INTERNAL';
41+
this.name = 'GitHubInternalError';
42+
this.stack = `${this.message}\n${new Error().stack}`;
43+
}
44+
};

github/index.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ const {
1414
getRemoteMarkdownPath,
1515
getRemoteRawPath
1616
} = require('./helpers');
17-
const { Client, constants, errorCode } = require('./client');
17+
const { RemoteFileNotFoundError } = require('./errors');
18+
const { Client, constants } = require('./client');
19+
20+
const ERR_REPOSITORY_EMPTY = 'ERR_REPOSITORY_EMPTY';
1821

1922
module.exports = class GithubHelper {
2023
/**
@@ -53,13 +56,13 @@ module.exports = class GithubHelper {
5356
if (!this.userId) await this.client.fetchGithubUser();
5457
await this.client.getHead();
5558
} catch (err) {
56-
if (err.code === errorCode.ERR_REPOSITORY_EMPTY) {
59+
if (err.code === ERR_REPOSITORY_EMPTY) {
5760
this.logger.debug('Repository seems to be empty. Initializing with a README.md');
5861
await this.client.initializeReadMe();
5962
return;
6063
}
6164

62-
throw new Error('Failed to initialize repository', err);
65+
throw err;
6366
}
6467
}
6568

@@ -79,9 +82,7 @@ module.exports = class GithubHelper {
7982
const blob = tree.find(({ type, path }) => type === constants.GITHUB_BLOB_TYPE && path === trimSlashes(filePath));
8083

8184
if (!blob) {
82-
const error = new Error(`File not found. [truncated_result=${truncated}]`);
83-
error.code = constants.ERR_FILE_NOT_FOUND;
84-
throw error;
85+
throw new RemoteFileNotFoundError(`File not found. [truncated_result=${truncated}]`);
8586
}
8687

8788
return this.client.getBlob(blob.sha);
@@ -100,7 +101,7 @@ module.exports = class GithubHelper {
100101
this.logger.debug(`Fetched metadata file at ${this.repoConfig.metadataFile}`);
101102
return JSON.parse(content);
102103
} catch (err) {
103-
if (err.code === constants.ERR_FILE_NOT_FOUND) {
104+
if (err.code === 'ERR_REMOTE_FILE_NOT_FOUND') {
104105
this.logger.info(`Metadata file not found on branch ${this.repoConfig.branch}. Creating new file...`);
105106
const timestamp = new Date().toISOString();
106107
const metadataContent = {
@@ -118,7 +119,7 @@ module.exports = class GithubHelper {
118119
return metadataContent;
119120
}
120121

121-
this.logger.error('Unknown error while fetching or creating sync metadata', err);
122+
this.logger.error('Unknown error while fetching or creating sync metadata');
122123
throw err;
123124
}
124125
}

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ launcher
1111
.withLoggerConfig({
1212
level: 'debug'
1313
})
14-
.module({ name: 'constants', path: './constants' })
14+
.module({ name: 'definitions', path: './definitions' })
1515
.module({ name: 'github', path: './github' })
1616
.module({ name: 'preprocessor', path: './preprocessor' })
1717
.module({ name: 'sync', path: './sync' })

preprocessor/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ class PreProcessor {
1313
this.container = container;
1414
this.logger = logger;
1515
this.platform = process.platform;
16-
this.constants = this.container.module('constants');
16+
const { constants, errors } = this.container.module('definitions');
17+
this.constants = constants;
18+
this.errors = errors;
1719
}
1820

1921
async processChangeSet(event, changedFile) {

0 commit comments

Comments
 (0)