Skip to content

Commit 2c6e1e0

Browse files
author
Ruben Bridgewater
committed
Improve error stacks in development and debug mode
1 parent ce44213 commit 2c6e1e0

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,35 @@ clients: 1, NodeJS: 6.2.0, Redis: 3.2.0, parser: javascript, connected by: tcp
757757

758758
To get debug output run your `node_redis` application with `NODE_DEBUG=redis`.
759759

760+
This is also going to result in good stack traces opposed to useless ones otherwise for any async operation.
761+
If you only want to have good stack traces but not the debug output run your application in development mode instead (`NODE_ENV=development`).
762+
763+
Good stack traces are only activated in development and debug mode as this results in a significant performance penalty.
764+
765+
___Comparison___:
766+
Useless stack trace:
767+
```
768+
ReplyError: ERR wrong number of arguments for 'set' command
769+
at parseError (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:158:12)
770+
at parseType (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:219:14)
771+
```
772+
Good stack trace:
773+
```
774+
ReplyError: ERR wrong number of arguments for 'set' command
775+
at new Command (/home/ruben/repos/redis/lib/command.js:9:902)
776+
at RedisClient.set (/home/ruben/repos/redis/lib/commands.js:9:3238)
777+
at Context.<anonymous> (/home/ruben/repos/redis/test/good_stacks.spec.js:20:20)
778+
at callFnAsync (/home/ruben/repos/redis/node_modules/mocha/lib/runnable.js:349:8)
779+
at Test.Runnable.run (/home/ruben/repos/redis/node_modules/mocha/lib/runnable.js:301:7)
780+
at Runner.runTest (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:422:10)
781+
at /home/ruben/repos/redis/node_modules/mocha/lib/runner.js:528:12
782+
at next (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:342:14)
783+
at /home/ruben/repos/redis/node_modules/mocha/lib/runner.js:352:7
784+
at next (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:284:14)
785+
at Immediate._onImmediate (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:320:5)
786+
at processImmediate [as _immediateCallback] (timers.js:383:17)
787+
```
788+
760789
## How to Contribute
761790
- Open a pull request or an issue about what you want to implement / change. We're glad for any help!
762791
- Please be aware that we'll only accept fully tested code.

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Features
1111
- The JS parser is from now on the new default as it is a lot faster than the hiredis parser
1212
- This is no BC as there is no changed behavior for the user at all but just a performance improvement. Explicitly requireing the Hiredis parser is still possible.
1313
- Added name property to all Redis functions (Node.js >= 4.0)
14+
- Improved stack traces in development and debug mode
1415

1516
Bugfixes
1617

index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ RedisClient.prototype.flush_and_error = function (error_attributes, options) {
348348
// Don't flush everything from the queue
349349
for (var command_obj = this[queue_names[i]].shift(); command_obj; command_obj = this[queue_names[i]].shift()) {
350350
var err = new errorClasses.AbortError(error_attributes);
351+
if (command_obj.error) {
352+
err.stack = err.stack + command_obj.error.stack.replace(/^Error.*?\n/, '\n');
353+
}
351354
err.command = command_obj.command.toUpperCase();
352355
if (command_obj.args && command_obj.args.length) {
353356
err.args = command_obj.args;
@@ -675,6 +678,9 @@ RedisClient.prototype.connection_gone = function (why, error) {
675678

676679
RedisClient.prototype.return_error = function (err) {
677680
var command_obj = this.command_queue.shift();
681+
if (command_obj.error) {
682+
err.stack = command_obj.error.stack.replace(/^Error.*?\n/, 'ReplyError: ' + err.message + '\n');
683+
}
678684
err.command = command_obj.command.toUpperCase();
679685
if (command_obj.args && command_obj.args.length) {
680686
err.args = command_obj.args;

lib/command.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
'use strict';
22

3+
var debug_mode = require('../').debug_mode;
4+
var betterStackTraces = process.env.NODE_ENV && process.env.NODE_ENV.toUpperCase() === 'DEVELOPMENT' || debug_mode;
35

46
function Command (command, args, callback, call_on_write) {
57
this.command = command;
68
this.args = args;
79
this.buffer_args = false;
810
this.callback = callback;
911
this.call_on_write = call_on_write;
12+
if (betterStackTraces) {
13+
this.error = new Error();
14+
}
1015
}
1116

1217
module.exports = Command;

0 commit comments

Comments
 (0)