Skip to content

Commit

Permalink
feat: Add additional context info when throw exception (#519)
Browse files Browse the repository at this point in the history
  • Loading branch information
congminh1254 authored Feb 15, 2024
1 parent 76646c1 commit b99a58d
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 22 deletions.
53 changes: 35 additions & 18 deletions src/box-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,18 @@ class BoxCommand extends Command {
}) failed with error:}`
);
let err = errorInfo.error;
let contextInfo;
if (err.response && err.response.body && err.response.body.context_info) {
contextInfo = formatObject(err.response.body.context_info);
// Remove color codes from context info
// eslint-disable-next-line no-control-regex
contextInfo = contextInfo.replace(/\u001b\[\d+m/gu, '');
// Remove \n with os.EOL
contextInfo = contextInfo.replace(/\n/gu, os.EOL);
}
let errMsg = chalk`{redBright ${
this.flags && this.flags.verbose ? err.stack : err.message
}${os.EOL}}`;
}${os.EOL}${contextInfo ? contextInfo + os.EOL : ''}}`;
this.info(errMsg);
});
}
Expand Down Expand Up @@ -902,21 +911,21 @@ class BoxCommand extends Command {
},
});

writeFunc = async(savePath) => {
writeFunc = async (savePath) => {
await pipeline(
stringifiedOutput,
appendNewLineTransform,
fs.createWriteStream(savePath, { encoding: 'utf8' })
);
};

logFunc = async() => {
logFunc = async () => {
await this.logStream(stringifiedOutput);
};
} else {
stringifiedOutput = await this._stringifyOutput(formattedOutputData);

writeFunc = async(savePath) => {
writeFunc = async (savePath) => {
await utils.writeFileAsync(savePath, stringifiedOutput + os.EOL, {
encoding: 'utf8',
});
Expand Down Expand Up @@ -959,19 +968,19 @@ class BoxCommand extends Command {
// Unroll iterator into array
if (typeof obj.next === 'function') {
output = [];
let entry = await obj.next();
while (!entry.done) {
output.push(entry.value);
let entry = await obj.next();
while (!entry.done) {
output.push(entry.value);

if (this.maxItemsReached(this.flags['max-items'], output.length)) {
break;
}

/* eslint-disable no-await-in-loop */
entry = await obj.next();
/* eslint-enable no-await-in-loop */
if (this.maxItemsReached(this.flags['max-items'], output.length)) {
break;
}
DEBUG.output('Unrolled iterable into %d entries', output.length);

/* eslint-disable no-await-in-loop */
entry = await obj.next();
/* eslint-enable no-await-in-loop */
}
DEBUG.output('Unrolled iterable into %d entries', output.length);
}

if (this.flags['id-only']) {
Expand Down Expand Up @@ -1213,7 +1222,7 @@ class BoxCommand extends Command {
wrapError(err) {
let messageMap = {
'invalid_grant - Refresh token has expired':
'Your refresh token has expired. \nPlease run this command "box login --name <ENVIRONMENT_NAME> --reauthorize" to reauthorize selected environment and then run your command again.'
'Your refresh token has expired. \nPlease run this command "box login --name <ENVIRONMENT_NAME> --reauthorize" to reauthorize selected environment and then run your command again.',
};

for (const key in messageMap) {
Expand Down Expand Up @@ -1247,10 +1256,18 @@ class BoxCommand extends Command {
DEBUG.execute('Got EEXIT code, exiting immediately');
return;
}

let contextInfo;
if (err.response && err.response.body && err.response.body.context_info) {
contextInfo = formatObject(err.response.body.context_info);
// Remove color codes from context info
// eslint-disable-next-line no-control-regex
contextInfo = contextInfo.replace(/\u001b\[\d+m/gu, '');
// Remove \n with os.EOL
contextInfo = contextInfo.replace(/\n/gu, os.EOL);
}
let errorMsg = chalk`{redBright ${
this.flags && this.flags.verbose ? err.stack : err.message
}${os.EOL}}`;
}${os.EOL}${contextInfo ? contextInfo + os.EOL : ''}}`;

// Write the error message but let the process exit gracefully with error code so stderr gets written out
// @NOTE: Exiting the process in the callback enables tests to mock out stderr and run to completion!
Expand Down
2 changes: 1 addition & 1 deletion src/modules/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class UserModule {
options.limit = flags.limit;
}

//forcing offset based pagination for now. Using filter_term causes infinite loop because next_marker is never null
// forcing offset based pagination for now. Using filter_term causes infinite loop because next_marker is never null
// if (flags.usemarker) {
// options.usemarker = flags.usemarker;
// }
Expand Down
4 changes: 4 additions & 0 deletions test/commands/bulk.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ describe('Bulk', () => {
expectedErrorOutput += ` [email protected]${os.EOL}`;
expectedErrorOutput += `) failed with error:${os.EOL}`;
expectedErrorOutput += `Unexpected API Response [409 Conflict | 170397861659135cc65a65] collaboration_already_exists${os.EOL}`;
expectedErrorOutput += `Conflicts:${os.EOL}`;
expectedErrorOutput += ` -${os.EOL}`;
expectedErrorOutput += ` Type: collaboration${os.EOL}`;
expectedErrorOutput += ` ID: '871642494'${os.EOL}`;
expectedErrorOutput += os.EOL;

assert.equal(ctx.stdout, expectedOutput + os.EOL);
Expand Down
31 changes: 28 additions & 3 deletions test/commands/folders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1171,9 +1171,26 @@ describe('Folders', () => {
...expectedBody,
description,
})
.reply(201, fixture)
.reply(409, {
type: 'error',
status: 409,
code: 'item_name_in_use',
context_info: {
conflicts: [
{
type: 'folder',
id: '12345',
name: 'New Folder'
}
]
},
help_url: 'http://developers.box.com/docs/#errors',
message: 'Item with the same name already exists',
request_id: '1wne91fxf8871ide'
})
)
.stdout()
.stderr()
.command([
'folders:create',
parentFolderId,
Expand All @@ -1182,8 +1199,16 @@ describe('Folders', () => {
'--json',
'--token=test'
])
.it('should send the description param when --description is passed', ctx => {
assert.equal(ctx.stdout, fixture);
.it('should catch and report errors with detailed context info', ctx => {
let expectedErrorOutput = `Unexpected API Response [409 Conflict | 1wne91fxf8871ide] item_name_in_use - Item with the same name already exists${os.EOL}`;
expectedErrorOutput += `Conflicts:${os.EOL}`;
expectedErrorOutput += ` -${os.EOL}`;
expectedErrorOutput += ` Type: folder${os.EOL}`;
expectedErrorOutput += ` ID: '12345'${os.EOL}`;
expectedErrorOutput += ` Name: New Folder${os.EOL}`;

assert.equal(ctx.stdout, '');
assert.equal(ctx.stderr, expectedErrorOutput);
});
});

Expand Down

0 comments on commit b99a58d

Please sign in to comment.