smart
smart2mo ago

Full stack traces from tests

I've noticed that stack traces emitted from tests are limited to 7ish lines. However, many errors start deeper and it's tough to find the error line from test failure reports. Is there a way to tune the number of lines emitted from the test ERRORS section? Or ideally, could stack traces be truncated in a way that emits stack frames in files hosted in a Deno.cwd() dir/subdir (i.e. user's code)?
5 Replies
smart
smart2mo ago
Here is a full error.stack trace when I catch the error and re-throw it:
PostgresError: column "signed_inat" of relation "users" does not exist
at ErrorResponse (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:791:26)
at handle (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:477:6)
at data (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:318:9)
at https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:30
at Array.forEach (<anonymous>)
at call (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:16)
at success (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:98:9)
at eventLoopTick (ext:core/01_core.js:168:7)
at cachedError (https://deno.land/x/postgresjs@v3.4.4/src/query.js:170:23)
at new Query (https://deno.land/x/postgresjs@v3.4.4/src/query.js:36:24)
at UserService.sql (https://deno.land/x/postgresjs@v3.4.4/src/index.js:113:11)
at UserService.signIn (file:///Users/mario/github/site/deno/src/services/user-service.ts:123:41) {
PostgresError: column "signed_inat" of relation "users" does not exist
at ErrorResponse (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:791:26)
at handle (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:477:6)
at data (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:318:9)
at https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:30
at Array.forEach (<anonymous>)
at call (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:16)
at success (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:98:9)
at eventLoopTick (ext:core/01_core.js:168:7)
at cachedError (https://deno.land/x/postgresjs@v3.4.4/src/query.js:170:23)
at new Query (https://deno.land/x/postgresjs@v3.4.4/src/query.js:36:24)
at UserService.sql (https://deno.land/x/postgresjs@v3.4.4/src/index.js:113:11)
at UserService.signIn (file:///Users/mario/github/site/deno/src/services/user-service.ts:123:41) {
Here is the error from the test output:
user services ... users can sign in with email and password => https://jsr.io/@std/testing/0.224.0/_test_suite.ts:323:15
error: PostgresError: column "signed_inat" of relation "users" does not exist
const error = Errors.postgres(parseError(x))
^
at ErrorResponse (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:791:26)
at handle (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:477:6)
at data (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:318:9)
at https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:30
at Array.forEach (<anonymous>)
at call (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:16)
at success (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:98:9)
user services ... users can sign in with email and password => https://jsr.io/@std/testing/0.224.0/_test_suite.ts:323:15
error: PostgresError: column "signed_inat" of relation "users" does not exist
const error = Errors.postgres(parseError(x))
^
at ErrorResponse (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:791:26)
at handle (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:477:6)
at data (https://deno.land/x/postgresjs@v3.4.4/src/connection.js:318:9)
at https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:30
at Array.forEach (<anonymous>)
at call (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:138:16)
at success (https://deno.land/x/postgresjs@v3.4.4/polyfills.js:98:9)
I noticed that the code to abbreviate errors is in fn abbreviate_test_error(js_error: &JsError) -> JsError { in deno/cli/tools/test/fmt.rs. It appears to support filtering user code errors, but I wonder why it's not working for me....
Deno AI Helper
Deno AI Helper2mo ago
The documentation indicates that starting from Deno 1.21, deno test has been improved to filter out stack frames that are coming from Deno’s internal code and show the line of code where the error originates. This means that the stack traces for thrown errors in tests should now be more informative and focused on the user's code rather than internal Deno code. Here's an example from the documentation showing the improved error reporting:
$ deno test test.ts
Check file:///dev/deno/test.ts
running 1 test from ./test.ts
error in a test ... FAILED (5ms)

failures:

./test.ts > error in a test
Error: boom!
throw new Error("boom!");
^
at file:///dev/deno/test.ts:2:9

failures:

./test.ts
error in a test

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (15ms)

error: Test failed
$ deno test test.ts
Check file:///dev/deno/test.ts
running 1 test from ./test.ts
error in a test ... FAILED (5ms)

failures:

./test.ts > error in a test
Error: boom!
throw new Error("boom!");
^
at file:///dev/deno/test.ts:2:9

failures:

./test.ts
error in a test

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (15ms)

error: Test failed
As you can see, the stack trace is concise and points directly to the user's code where the error was thrown. The documentation does not mention a way to tune the number of lines emitted from the test ERRORS section or a method to truncate stack traces based on files in a specific directory like Deno.cwd(). However, the improvements made should already provide a better testing experience by focusing on the user's code. If you find that the stack traces are still not providing enough context for debugging, it might be worth providing feedback to the Deno team as they have expressed interest in further improving the test reporter in future releases. 🦕
marvinh.
marvinh.2mo ago
@smart You can set the stack trace limit by a custom value in your code:
Error.stackTraceLimit = Infinity;
Error.stackTraceLimit = Infinity;
smart
smart2mo ago
Thanks I'll give that a try!
thesmart
thesmart2mo ago
Hmm that's not in the typespec for me... This is a Node.js feature?
Property 'stackTraceLimit' does not exist on type 'ErrorConstructor'.deno-ts(2339)
Property 'stackTraceLimit' does not exist on type 'ErrorConstructor'.deno-ts(2339)
And when I add // @ts-ignore and set it anyway, it doesn't impact the deno test strack trace truncation.