Fix noisy nodejs runtime errors (#6995)

This commit is contained in:
Evan Boyle 2021-05-10 15:04:03 -07:00 committed by GitHub
parent 815f42d8a5
commit 15418b6789
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 12 deletions

View file

@ -15,5 +15,8 @@
- [auto/python] - Export missing `ProjectBackend` type
[#6984](https://github.com/pulumi/pulumi/pull/6984)
- [sdk/nodejs] - Fix noisy errors.
[#6995](https://github.com/pulumi/pulumi/pull/6995)
- Config: Avoid emitting integers in objects using exponential notation.
[#7005](https://github.com/pulumi/pulumi/pull/7005)

View file

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import * as log from "../../log";
// The very first thing we do is set up unhandled exception and rejection hooks to ensure that these
// events cause us to exit with a non-zero code. It is critically important that we do this early:
// if we do not, unhandled rejections in particular may cause us to exit with a 0 exit code, which
@ -32,8 +34,10 @@ const loggedErrors = new Set<Error>();
let programRunning = false;
const uncaughtHandler = (err: Error) => {
uncaughtErrors.add(err);
if (!programRunning) {
console.error(err.stack || err.message || ("" + err));
if (!programRunning && !loggedErrors.has(err)) {
log.error(err.stack || err.message || ("" + err));
// dedupe errors that we're reporting when the program is not running
loggedErrors.add(err);
}
};
@ -154,7 +158,8 @@ function main(args: string[]): void {
const promise: Promise<void> = require("./run").run(
argv,
/*programStarted: */ () => programRunning = true,
/*reportLoggedError:*/ (err: Error) => loggedErrors.add(err));
/*reportLoggedError:*/ (err: Error) => loggedErrors.add(err),
/*isErrorReported: */ (err: Error) => loggedErrors.has(err));
// when the user's program completes successfully, set programRunning back to false. That way, if the Pulumi
// scaffolding code ends up throwing an exception during teardown, it will get printed directly to the console.

View file

@ -133,7 +133,8 @@ function throwOrPrintModuleLoadError(program: string, error: Error): void {
/** @internal */
export function run(argv: minimist.ParsedArgs,
programStarted: () => void,
reportLoggedError: (err: Error) => void) {
reportLoggedError: (err: Error) => void,
isErrorReported: (err: Error) => boolean) {
// If there is a --pwd directive, switch directories.
const pwd: string | undefined = argv["pwd"];
if (pwd) {
@ -174,19 +175,15 @@ export function run(argv: minimist.ParsedArgs,
process.argv = [ process.argv[0], process.argv[1], ...programArgs ];
// Set up the process uncaught exception, unhandled rejection, and program exit handlers.
const errorSet = new Set<Error>();
const uncaughtHandler = (err: Error) => {
// In node, if you throw an error in a chained promise, but the exception is not finally
// handled, then you can end up getting an unhandledRejection for each exception/promise
// pair. Because the exception is the same through all of these, we keep track of it and
// only report it once so the user doesn't get N messages for the same thing.
if (errorSet.has(err)) {
if (isErrorReported(err)) {
return;
}
errorSet.add(err);
// Default message should be to include the full stack (which includes the message), or
// fallback to just the message if we can't get the stack.
//

View file

@ -120,7 +120,7 @@ export function getResource(res: Resource, props: Inputs, custom: boolean, urn:
// Now run the operation, serializing the invocation if necessary.
const opLabel = `monitor.getResource(${label})`;
runAsyncResourceOp(opLabel, async () => {
let resp: any;
let resp: any = {};
let err: Error | undefined;
try {
if (monitor) {
@ -226,7 +226,7 @@ export function readResource(res: Resource, t: string, name: string, props: Inpu
// Now run the operation, serializing the invocation if necessary.
const opLabel = `monitor.readResource(${label})`;
runAsyncResourceOp(opLabel, async () => {
let resp: any;
let resp: any = {};
let err: Error | undefined;
try {
if (monitor) {
@ -340,7 +340,7 @@ export function registerResource(res: Resource, t: string, name: string, custom:
// Now run the operation, serializing the invocation if necessary.
const opLabel = `monitor.registerResource(${label})`;
runAsyncResourceOp(opLabel, async () => {
let resp: any;
let resp: any = {};
let err: Error | undefined;
try {
if (monitor) {