question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Stack traces are truncated / lack client side stack trace

See original GitHub issue

When pg throws an error, I often have trouble finding the place in my code where this is actually coming from. For some reasons the exceptions thrown by pg seem to contain strange stack trace, and in particular, the stack trace doesn’t contain any client side code. I’m actually on TypeScript running through ts-node, but I think I can reproduce the behavior with plain JS. Here is a minimal example:

const pg = require("pg");

async function provokeExceptionPg() {
  let client = new pg.Client();
  await client.connect();
}

provokeExceptionPg().catch((err) => console.log(err));

The output of running node index.js is just:

Error: connect ECONNREFUSED 127.0.0.1:5432
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 5432
}

Note that the output is completely lacking any information of client side code, which in this case would just be my index.js. To demonstrate the kind of traceback I’d expect, I can for instance replace new pg.Client() by something broken like new pg.ClientNonexisting(). This results in a stack trace that clearly shows the client side stack leading to the error:

TypeError: pg.ClientNonexisting is not a constructor
    at provokeExceptionPg (/tmp/test_project/index.js:4:16)
    at Object.<anonymous> (/tmp/test_project/index.js:8:1)
    [...]

The lack of client side stack traces makes it very hard to understand where errors are coming from in a more complex code base. Is there any way to get more meaningful stack traces out of pg or would that make sense as a feature request?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:6
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
javier-garcia-meteologicacommented, Jun 7, 2022

It seems that using bluebird is not a future-proof solution. Take a look at this warning.

Please use native promises instead if at all possible. Native Promises have been stable in Node.js and browsers for around 6 years now and they have been fast for around 3. Bluebird still offers some useful utility methods and you can use it - but please consider native promises first. […] Currently - it is only recommended to use Bluebird if you need to support old browsers or EoL Node.js or as an intermediate step to use warnings/monitoring to find bugs.

As a workaround, here is this wrapper around native promises to augment stack traces

const PromiseWithAugmentedStackTrace = function PromiseWithAugmentedStackTrace <T> (
  executor: (
    resolve: (value: T | PromiseLike<T>) => void,
    reject: (reason?: unknown) => void
  ) => void
): Promise<T> {
  return new Promise(executor)
    .catch(err => {
      const infoErr = new Error();

      if (infoErr.stack != null && typeof err === 'object' && err != null) {
        if (typeof (err as Error).stack === 'string') {
          (err as Error).stack = [
            (err as Error).stack,
            'From previous event:',
            infoErr.stack.split('\n').slice(1).join('\n') // Remove first line
          ].join('\n');
        } else {
          (err as Error).stack = infoErr.stack;
        }
      }

      throw err;
    });
} as unknown as PromiseConstructor;

PromiseWithAugmentedStackTrace.resolve = <T>(value?: T | PromiseLike<T>) => Promise.resolve(value);
PromiseWithAugmentedStackTrace.reject = (reason: unknown) => Promise.reject(reason);
PromiseWithAugmentedStackTrace.race = <T>(values: Iterable<T | PromiseLike<T>>) => Promise.race(values);
PromiseWithAugmentedStackTrace.all = <T>(values: Iterable<T | PromiseLike<T>>) => Promise.all(values);
PromiseWithAugmentedStackTrace.any = <T>(values: Iterable<T | PromiseLike<T>>) => Promise.any(values);
PromiseWithAugmentedStackTrace.allSettled = <T>(values: Iterable<T | PromiseLike<T>>) => Promise.allSettled(values);

It can be used with node-postgres as follows

const pool = new pg.Pool({
  ...connectionConfig,
  Promise: PromiseWithAugmentedStackTrace
});
2reactions
vitaly-tcommented, Feb 14, 2021

Bring your own promise - Bluebird, and enable Long Stack Traces.

const Promise = require('bluebird');

Promise.config({
    longStackTraces: true
});

// creating pool with custom Promise:
const pool = new Pool({Promise});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Javascript stack traces are truncated - node.js
You can assign to the stackTraceLimit property of the Error constructor, which defaults to 10: function blowUp(n) { if(n > 100) { throw...
Read more >
Some stack traces are truncated - SDKs - #sentry
Some errors are truncated which both limits the stack trace and prevents Sentry from rendering a pretty stack trace.
Read more >
Java: Collapsing multiline stack traces into a single log event ...
Folding a multi-line Java stack trace into a single line means that it can be treated as a single unit by a centralized...
Read more >
Method trimming and stack traces - BMC Documentation
Method request trees in the code section are trimmed by default, ... If the instance has latency violations, the full stack trace is...
Read more >
Chapter 6: Layouts - Logback
Other segments may be shortened to at most a single character but are never ... Outputs the stack trace of the exception associated...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found