in src/mongo/MongoShell.ts [74:149]
public async executeScript(script: string): Promise<string> {
script = convertToSingleLine(script);
let stdOut = "";
const sentinel = createSentinel();
const disposables: vscode.Disposable[] = [];
try {
// eslint-disable-next-line @typescript-eslint/no-misused-promises, no-async-promise-executor
const result = await new Promise<string>(async (resolve, reject) => {
try {
startScriptTimeout(this._timeoutSeconds, reject);
// Hook up events
disposables.push(
this._process.onStdOut(text => {
stdOut += text;
// eslint-disable-next-line prefer-const
let { text: stdOutNoSentinel, removed } = removeSentinel(stdOut, sentinel);
if (removed) {
// The sentinel was found, which means we are done.
// Change the "type 'it' for more" message to one that doesn't ask users to type anything,
// since we're not currently interactive like that.
// CONSIDER: Ideally we would allow users to click a button to iterate through more data,
// or even just do it for them
stdOutNoSentinel = stdOutNoSentinel.replace(mongoShellMoreMessage, extensionMoreMessage);
resolve(stdOutNoSentinel);
}
}));
disposables.push(
this._process.onStdErr(text => {
// Mongo shell only writes to STDERR for errors relating to starting up. Script errors go to STDOUT.
// So consider this an error.
// (It's okay if we fire this multiple times, the first one wins.)
reject(wrapCheckOutputWindow(text.trim()));
}));
disposables.push(
this._process.onError(error => {
reject(error);
}));
// Write the script to STDIN
if (script) {
this._process.writeLine(script);
}
// Mark end of result by sending the sentinel wrapped in quotes so the console will spit
// it back out as a string value after it's done processing the script
const quotedSentinel = `"${sentinel}"`;
this._process.writeLine(quotedSentinel); // (Don't display the sentinel)
} catch (error) {
// new Promise() doesn't seem to catch exceptions in an async function, we need to explicitly reject it
if ((<{ code?: string }>error).code === 'EPIPE') {
// Give a chance for start-up errors to show up before rejecting with this more general error message
await delay(500);
// eslint-disable-next-line no-ex-assign
error = new Error("The process exited prematurely.");
}
reject(wrapCheckOutputWindow(error));
}
});
return result.trim();
}
finally {
// Dispose event handlers
for (const d of disposables) {
d.dispose();
}
}
}