public async executeScript()

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();
            }
        }
    }