alsatian icon indicating copy to clipboard operation
alsatian copied to clipboard

No stack trace is provided for unhandled errors during tests

Open jhm-ciberman opened this issue 7 years ago • 4 comments

No stack trace is provided for unhandled errors during tests

FAIL: checkGMLFeaturesMatchDocs should validate a valid script with a non optional param
The test threw an unhandled error.
Expected: no unhandled errors to be thrown
  Actual: an unhandled error

jhm-ciberman avatar Jan 15 '18 22:01 jhm-ciberman

This one is very strange - I was sure that we were printing out the stack. Do you have a link to this test @jhm-ciberman?

jamesadarich avatar Jan 15 '18 23:01 jamesadarich

The test was generated by a typo (I wrote throw 3; instead of return 3;). As fas as I know throwing literals does not generate stack traces. For example throw "my error"; would not generate a stack trace. Instead this throw new Exception("my error"); will generate a stack trace inside the Exception instance.

The code used was the following. If you need, I can create a fork of my own project and reproduce the bug inside it so you can take a closer look:

        @Test("checkGMLFeaturesMatchDocs should validate a valid script with a non optional param")
	public checkGMLFeaturesMatchDocs_Valid_Params_nonOptional() {
		class MockGMLParser implements IGMLParser {
			public countFixedArguments(): number {
				throw 1; //Note the typo of "throw" instead of "return"
			}
			public countOptionalArguments(): number {
				throw 0; //Note the typo of "throw" instead of "return"
			}
			public hasReturn(): boolean {
				throw true; //Note the typo of "throw" instead of "return"
			}
		}

		const docScript = new DocScript();
		const argument0 = this._createParam("My param", "param_name", false, "real");
		docScript.params.push(argument0);
		docScript.undocumented = false;

		const validator = new Validator(docScript, this.config);
		const parser = new MockGMLParser();
		Expect(validator.checkGMLFeaturesMatchDocs(parser)).toBe(true);
	}

jhm-ciberman avatar Jan 15 '18 23:01 jhm-ciberman

Thanks @jhm-ciberman I think this is probably enough to go on for now but I suspect the reason is the literal types don't have a trace associated with them but we may still be able to get something useful out of this scenario.

jamesadarich avatar Jan 16 '18 00:01 jamesadarich

JavaScript allows throwing anything, so sadly there won't be a great stack trace for this scenario.

However, we can still create a stack trace, and manipulate the stack if needed.

Proof Of Concept

try {
    throw 1;
}
catch (err) {
    const stack = new Error().stack;

    console.log(stack);

    const newStack = stack.replace(/\:(\d+)\:(\d+)/, ':2:11');

    console.log(newStack);
}

Output

Error
    at Object.<anonymous> (D:\Github\alsatian\foo.js:5:19)
    at Module._compile (internal/modules/cjs/loader.js:702:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:744:10)
    at startup (internal/bootstrap/node.js:238:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:572:3)
Error
    at Object.<anonymous> (D:\Github\alsatian\foo.js:2:11)
    at Module._compile (internal/modules/cjs/loader.js:702:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:744:10)
    at startup (internal/bootstrap/node.js:238:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:572:3)

pathurs avatar Jul 18 '18 10:07 pathurs