Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/browser-repl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@leafygreen-ui/palette": "^2.0.0",
"@leafygreen-ui/syntax": "^2.2.0",
"@mongosh/browser-runtime-core": "0.0.0-dev.0",
"@mongosh/errors": "0.0.0-dev.0",
"@mongosh/history": "0.0.0-dev.0",
"@mongosh/i18n": "0.0.0-dev.0",
"@mongosh/node-runtime-worker-thread": "0.0.0-dev.0",
Expand Down
12 changes: 12 additions & 0 deletions packages/browser-repl/src/components/types/error-output.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { isShouldReportAsBugError } from '@mongosh/errors';

import { SimpleTypeOutput } from './simple-type-output';
import { Expandable } from '../utils/expandable';
Expand All @@ -26,6 +27,16 @@ export class ErrorOutput extends Component<ErrorOutputProps> {
return this.props.value.stack.split('\n').slice(1).join('\n');
}

formatErrorBugReportInfo(): JSX.Element | undefined {
if (isShouldReportAsBugError(this.props.value)) {
return (<div>
This is an error inside mongosh.
Please <a href="https://jira.mongodb.org/projects/MONGOSH/issues" target="_blank">file a bug report for the MONGOSH project</a>.
</div>);
}
return undefined;
}

formatErrorInfo(): JSX.Element | undefined {
if (this.props.value.errInfo) {
return (<div>
Expand All @@ -50,6 +61,7 @@ export class ErrorOutput extends Component<ErrorOutputProps> {
return (<div>
{this.renderCollapsed(toggle)}
<div>
{this.formatErrorBugReportInfo()}
{this.formatErrorInfo()}
{this.formatErrorResult()}
<pre>{this.formatStack()}</pre>
Expand Down
13 changes: 10 additions & 3 deletions packages/cli-repl/src/cli-repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,18 +276,21 @@ class CliRepl {
}
}

get logFilePath(): string {
return this.shellHomeDirectory.localPath(`${this.logId}_log`);
}

/**
* Open a writable stream for the current log file.
*/
async openLogStream(): Promise<Writable> {
const path = this.shellHomeDirectory.localPath(`${this.logId}_log`);
await this.cleanupOldLogfiles();
try {
const stream = createWriteStream(path, { mode: 0o600 });
const stream = createWriteStream(this.logFilePath, { mode: 0o600 });
await once(stream, 'ready');
return stream;
} catch (err) {
this.warnAboutInaccessibleFile(err, path);
this.warnAboutInaccessibleFile(err, this.logFilePath);
return new Writable({
write(chunk, enc, cb) {
// Just ignore log data if there was an error.
Expand Down Expand Up @@ -492,6 +495,10 @@ class CliRepl {
throw e;
}
}

bugReportErrorMessageInfo(): string {
return `Please include the log file for this session (${this.logFilePath}).`;
}
}

export default CliRepl;
8 changes: 8 additions & 0 deletions packages/cli-repl/src/format-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import util from 'util';
import stripAnsi from 'strip-ansi';
import clr from './clr';
import { HelpProperties, CollectionNamesWithTypes } from '@mongosh/shell-api';
import { isShouldReportAsBugError } from '@mongosh/errors';

type EvaluationResult = {
value: any;
Expand All @@ -20,6 +21,7 @@ type FormatOptions = {
maxArrayLength?: number;
maxStringLength?: number;
showStackTraces?: boolean;
bugReportErrorMessageInfo?: string;
};

/**
Expand Down Expand Up @@ -178,6 +180,12 @@ export function formatError(error: Error, options: FormatOptions): string {
let result = '';
if (error.name) result += `\r${clr(error.name, ['bold', 'red'], options)}: `;
if (error.message) result += error.message;
if (isShouldReportAsBugError(error)) {
result += '\nThis is an error inside mongosh. Please file a bug report for the MONGOSH project here: https://jira.mongodb.org/projects/MONGOSH/issues.';
if (options.bugReportErrorMessageInfo) {
result += `\n${options.bugReportErrorMessageInfo}`;
}
}
if (error.name === 'SyntaxError') {
if (!options.colors) {
// Babel applies syntax highlighting to its errors by default.
Expand Down
6 changes: 4 additions & 2 deletions packages/cli-repl/src/mongosh-repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type MongoshIOProvider = Omit<ConfigProvider<CliUserConfig>, 'validateCon
exit(code?: number): Promise<never>;
readFileUTF8(filename: string): Promise<{ contents: string, absolutePath: string }>;
startMongocryptd(): Promise<AutoEncryptionOptions['extraOptions']>;
bugReportErrorMessageInfo?(): string | undefined;
};

export type MongoshNodeReplOptions = {
Expand Down Expand Up @@ -599,14 +600,15 @@ class MongoshNodeRepl implements EvaluationListener {
return clr(text, style, this.getFormatOptions());
}

getFormatOptions(): { colors: boolean, compact: number | boolean, depth: number, showStackTraces: boolean } {
getFormatOptions(): { colors: boolean, compact: number | boolean, depth: number, showStackTraces: boolean, bugReportErrorMessageInfo?: string } {
const output = this.output as WriteStream;
return {
colors: this._runtimeState?.repl?.useColors ??
(output.isTTY && output.getColorDepth() > 1),
compact: this.inspectCompact,
depth: this.inspectDepth,
showStackTraces: this.showStackTraces
showStackTraces: this.showStackTraces,
bugReportErrorMessageInfo: this.ioProvider.bugReportErrorMessageInfo?.()
};
}

Expand Down
6 changes: 6 additions & 0 deletions packages/cli-repl/test/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ describe('e2e', function() {
shell.writeInputLine('process.exitCode = 42; quit()');
expect(await onExit).to.equal(42);
});
it('decorates internal errors with bug reporting information', async() => {
const err = await shell.executeLine('throw Object.assign(new Error("foo"), { code: "COMMON-90001" })');
expect(err).to.match(/^Error: foo$/m);
expect(err).to.match(/^This is an error inside mongosh\. Please file a bug report for the MONGOSH project here: https:\/\/jira.mongodb.org\/projects\/MONGOSH\/issues\.$/m);
expect(err).to.match(/^Please include the log file for this session \(.+[/\\][a-f0-9]{24}_log\)\.$/m);
});
});
describe('set db', () => {
for (const { mode, dbname, dbnameUri } of [
Expand Down
2 changes: 1 addition & 1 deletion packages/errors/src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('errors', () => {
const error = new MongoshInternalError('Something went wrong.');
expect(error).to.be.instanceOf(MongoshBaseError);
expect(error.name).to.be.equal('MongoshInternalError');
expect(error.message).to.be.equal('[COMMON-90001] Something went wrong.\nThis is an error inside mongosh. Please file a bug report for the MONGOSH project here: https://jira.mongodb.org/projects/MONGOSH/issues.');
expect(error.message).to.be.equal('[COMMON-90001] Something went wrong.');
expect(error.code).to.be.equal(CommonErrors.UnexpectedInternalError);
expect(error.scope).to.be.equal('COMMON');
});
Expand Down
8 changes: 6 additions & 2 deletions packages/errors/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ function getScopeFromErrorCode(code: string | null | undefined): string | undefi
return !match ? undefined : match[1];
}

function isShouldReportAsBugError(err: Error & { code?: string }): boolean {
return err?.code === CommonErrors.UnexpectedInternalError;
}

abstract class MongoshBaseError extends Error {
readonly code: string | undefined;
readonly scope: string | undefined;
Expand All @@ -32,8 +36,7 @@ class MongoshInternalError extends MongoshBaseError {
constructor(message: string, metadata?: Object) {
super(
'MongoshInternalError',
`${message}
This is an error inside mongosh. Please file a bug report for the MONGOSH project here: https://jira.mongodb.org/projects/MONGOSH/issues.`,
message,
CommonErrors.UnexpectedInternalError,
metadata
);
Expand Down Expand Up @@ -82,6 +85,7 @@ class MongoshCommandFailed extends MongoshBaseError {

export {
getScopeFromErrorCode,
isShouldReportAsBugError,
MongoshBaseError,
MongoshWarning,
MongoshRuntimeError,
Expand Down