From 8df6f9e54469902a3d1da30a57cbfbe6900f977d Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 25 Apr 2011 12:22:18 -0700 Subject: [PATCH] Close #974 Properly report traceless errors. Also, tests for the same. --- src/node.cc | 17 ++++++++++++--- test/message/stack_overflow.js | 33 +++++++++++++++++++++++++++++ test/message/stack_overflow.out | 6 ++++++ test/message/throw_custom_error.js | 30 ++++++++++++++++++++++++++ test/message/throw_custom_error.out | 6 ++++++ test/message/throw_non_error.js | 30 ++++++++++++++++++++++++++ test/message/throw_non_error.out | 6 ++++++ 7 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 test/message/stack_overflow.js create mode 100644 test/message/stack_overflow.out create mode 100644 test/message/throw_custom_error.js create mode 100644 test/message/throw_custom_error.out create mode 100644 test/message/throw_non_error.js create mode 100644 test/message/throw_non_error.out diff --git a/src/node.cc b/src/node.cc index fa2fab2ab1..fa64bb9902 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1274,13 +1274,24 @@ static void ReportException(TryCatch &try_catch, bool show_line) { String::Utf8Value trace(try_catch.StackTrace()); - if (trace.length() > 0) { + // range errors have a trace member set to undefined + if (trace.length() > 0 && !try_catch.StackTrace()->IsUndefined()) { fprintf(stderr, "%s\n", *trace); } else { // this really only happens for RangeErrors, since they're the only - // kind that won't have all this info in the trace. + // kind that won't have all this info in the trace, or when non-Error + // objects are thrown manually. Local er = try_catch.Exception(); - String::Utf8Value msg(!er->IsObject() ? er->ToString() + bool isErrorObject = er->IsObject() && + !(er->ToObject()->Get(String::New("message"))->IsUndefined()) && + !(er->ToObject()->Get(String::New("name"))->IsUndefined()); + + if (isErrorObject) { + String::Utf8Value name(er->ToObject()->Get(String::New("name"))); + fprintf(stderr, "%s: ", *name); + } + + String::Utf8Value msg(!isErrorObject ? er->ToString() : er->ToObject()->Get(String::New("message"))->ToString()); fprintf(stderr, "%s\n", *msg); } diff --git a/test/message/stack_overflow.js b/test/message/stack_overflow.js new file mode 100644 index 0000000000..d8f89f0c52 --- /dev/null +++ b/test/message/stack_overflow.js @@ -0,0 +1,33 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); + +common.error('before'); + +// stack overflow +function stackOverflow() { + stackOverflow(); +} +stackOverflow(); + +common.error('after'); diff --git a/test/message/stack_overflow.out b/test/message/stack_overflow.out new file mode 100644 index 0000000000..8269698cf7 --- /dev/null +++ b/test/message/stack_overflow.out @@ -0,0 +1,6 @@ +before + +node.js:134 + throw e; // process.nextTick error, or 'error' event on first tick + ^ +RangeError: Maximum call stack size exceeded diff --git a/test/message/throw_custom_error.js b/test/message/throw_custom_error.js new file mode 100644 index 0000000000..ef9fd3e0f7 --- /dev/null +++ b/test/message/throw_custom_error.js @@ -0,0 +1,30 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); + +common.error('before'); + +// custom error throwing +throw { name: 'MyCustomError', message: 'This is a custom message' }; + +common.error('after'); diff --git a/test/message/throw_custom_error.out b/test/message/throw_custom_error.out new file mode 100644 index 0000000000..5279758ed5 --- /dev/null +++ b/test/message/throw_custom_error.out @@ -0,0 +1,6 @@ +before + +node.js:134 + throw e; // process.nextTick error, or 'error' event on first tick + ^ +MyCustomError: This is a custom message diff --git a/test/message/throw_non_error.js b/test/message/throw_non_error.js new file mode 100644 index 0000000000..9d5d4a9611 --- /dev/null +++ b/test/message/throw_non_error.js @@ -0,0 +1,30 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); + +common.error('before'); + +// custom error throwing +throw { foo : 'bar' }; + +common.error('after'); diff --git a/test/message/throw_non_error.out b/test/message/throw_non_error.out new file mode 100644 index 0000000000..7c22d2f0b8 --- /dev/null +++ b/test/message/throw_non_error.out @@ -0,0 +1,6 @@ +before + +node.js:134 + throw e; // process.nextTick error, or 'error' event on first tick + ^ +[object Object]