How can I get more error details from a javascript catch?
Are there more parameters to get more details from the caught error.
try {
var s = null;
var t = s.toString();
} catch(err) {
alert(err);
}
The Error Object has several properties that you can use. One property you can use to get the message of the error, is .message, as in:
catch(err) {
alert(err.message);
}
The .name property returns the type of error as in:
catch(err) {
x = err.name;
// ... do something based on value of x
}
The name describes the type of error, and the value of .name can be : EvalError, RangeError, ReferenceError, SyntaxError, TypeError , and URIError. You may decide to handle the error differently depending on the error type which is returned by the .name property.
A good tutorial can be found on JavaScriptKit. The is also an article on the error object at Mozilla Developer Network.
Check this link out:
Reference to Error.prototype
Basically you have err.name and err.message.
You also have a few vendor-specific extensions:
Microsoft => err.description and err.number.
Mozilla => err.fileName, err.lineNumber and err.stack.
function message()
{
try
{
}
catch(err)
{
alert(err.message);
}
}
SEE HERE and HERE
Related
I have application where some critical issues are reported with console.error but are not thrown so application might continue to run - possibly in crippled state.
It's necessary to report also console.error issues, but Sentry (Raven) library send to server only thrown exceptions.
Does someone knows how to solve this nicely ?
(ideally without need to rewrite all console.error calls, cause also some vendor libraries might still write output just into console)
As user #kumar303 mentioned in his comment to the question ... you can use the JS console integration Sentry.Integrations.CaptureConsole.
See https://docs.sentry.io/platforms/javascript/configuration/integrations/plugin/#captureconsole for documentation.
At the end you JS code to setup Sentry looks as follows:
import * as Sentry from '#sentry/browser';
import { CaptureConsole } from '#sentry/integrations';
Sentry.init({
dsn: 'https://your-sentry-server-dsn',
integrations: [
new CaptureConsole({
levels: ['error']
})
],
release: '1.0.0',
environment: 'prod',
maxBreadcrumbs: 50
})
If then someone calls console.error a new event will sent to sentry.
Here's a more robust override solution
// creating function declarations for better stacktraces (otherwise they'd be anonymous function expressions)
var oldConsoleError = console.error;
console.error = reportingConsoleError; // defined via function hoisting
function reportingConsoleError() {
var args = Array.prototype.slice.call(arguments);
Sentry.captureException(reduceConsoleArgs(args), { level: 'error' });
return oldConsoleError.apply(console, args);
};
var oldConsoleWarn = console.warn;
console.warn = reportingConsoleWarn; // defined via function hoisting
function reportingConsoleWarn() {
var args = Array.prototype.slice.call(arguments);
Sentry.captureMessage(reduceConsoleArgs(args), { level: 'warning' });
return oldConsoleWarn.apply(console, args);
}
function reduceConsoleArgs(args) {
let errorMsg = args[0];
// Make sure errorMsg is either an error or string.
// It's therefore best to pass in new Error('msg') instead of just 'msg' since
// that'll give you a stack trace leading up to the creation of that new Error
// whereas if you just pass in a plain string 'msg', the stack trace will include
// reportingConsoleError and reportingConsoleCall
if (!(errorMsg instanceof Error)) {
// stringify all args as a new Error (which creates a stack trace)
errorMsg = new Error(
args.reduce(function(accumulator, currentValue) {
return accumulator.toString() + ' ' + currentValue.toString();
}, '')
);
}
return errorMsg;
}
Based on #Marc Schmid's solution I came up with the following working example, if you link to the Sentry CDN files.
<script src="https://browser.sentry-cdn.com/5.11.1/bundle.min.js" integrity="sha384-r7/ZcDRYpWjCNXLUKk3iuyyyEcDJ+o+3M5CqXP5GUGODYbolXewNHAZLYSJ3ZHcV" crossorigin="anonymous"></script>
<!-- https://github.com/getsentry/sentry-javascript/issues/1976#issuecomment-492260648 -->
<script src="https://browser.sentry-cdn.com/5.11.1/captureconsole.min.js"></script>
<script>
Sentry.init({
dsn: 'https://abcdef1234567890#sentry.io/012345',
debug: false,
integrations: [
new Sentry.Integrations.CaptureConsole({
levels: ['error']
})
],
});
</script>
Found a little hacky solution:
const consoleError = console.error;
console.error = function(firstParam) {
const response = consoleError.apply(console, arguments);
Raven.captureException(firstParam, { level: 'error' });
return response;
};
It just wraps console.error and report each of error logs in console to Raven (Sentry).
If someone have nicer approach (maybe some hidden feature of Sentry) please feel free to share!
I wrote a library that is going this using your Sentry instance.
https://github.com/aneldev/dyna-sentry
Snippet for taking screenshot on Test Failure
afterEach(function() {
var spec = jasmine.getEnv().currentSpec;
var passed = spec.results().passed();
if (!passed) {
browser.takeScreenshot().then(function(png) {
writeScreenShot(png, "screenshot.png");
});
}
function writeScreenShot(data, filename) {
var stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}
});
Console error
Message:
Failed: Cannot read property 'results' of undefined
Stack:
TypeError: Cannot read property 'results' of undefined
at Object.<anonymous>
it returns undefined here,
var spec = jasmine.getEnv().currentSpec;
console.log(spec);
Looks like issues due to Jasmine 2; any alternate solutions also welcome! I use Jasmine 2
As of Jasmine 2.0, env.currentSpec is no longer supported.
https://github.com/jasmine/jasmine/issues/1212
"var spec" is not being set to anything. That means "jasmine.getEnv().currentSpec" is not working for whatever reason.
I keep getting this error Failed with: TypeError: Cannot read property 'success' of undefined which i cannot figure out the problem
Parse.Cloud.httpRequest(
{
url:url,
success:function(httpResponse)
{
var Day = Parse.Object.extend("TestDay");
var queryToday = new Parse.Query(Day);
queryToday.equalTo("dayday", day);
queryToday.equalTo("daymonth", month);
queryToday.equalTo("dayyear", year);
queryToday.equalTo("owner", theUser);
queryToday.first().then(function(dayObject) <---line 662
{
if(dayObject == undefined)
{
console.log("not found");
}
else
{
console.log(dayObject);
}
}, function(error)
{
console.log("first failed");
});
}
});
Failed with: TypeError: Cannot read property 'success' of undefined
at Object.b.Query.first (Parse.js:1:57000)
at Object.Parse.Cloud.httpRequest.success (main.js:662:48)
How do you know that's the line? I mean, are you on web using the console?
Is there something else to know? Like are you working on a cloud function?
My guess is that returning dayObject.save(); doesn't work. Try using a console.log(dayObject) to know exactly the query's response. It may happens that you'll have to use a conditional as follows:
if(dayObject == undefined){
return Parse.Promise.error("Not Found");
}else{
dayObject.increment("totalnumberofphotos");
return dayObject.save();
}
I have found the answer to my question. it is because the parse sdk on cloud is too low version, so i have to update it to the latest one and it works now. thank you very much
In my NodeJS program, I parse some user JSON file.
So I use :
this.config = JSON.parse(fs.readFileSync(path));
The problem is that if the json file is not correctly formated, the error thrown is like:
undefined:55
},
^
SyntaxError: Unexpected token }
at Object.parse (native)
at new MyApp (/path/to/docker/lib/node_modules/myApp/lib/my-app.js:30:28)
...
As it is not really user friendly I would like to throw an Error specifying some user friendly message (like "your config file is not well formated") but I want to keep the stacktrace in order to point to the problematic line.
In the Java world I used throw new Exception("My user friendly message", catchedException) in order to have the original exception which caused that one.
How is it possible in the JS world?
What I finally did is:
try {
this.config = JSON.parse(fs.readFileSync(path));
} catch(err) {
var newErr = new Error('Problem while reading the JSON file');
newErr.stack += '\nCaused by: '+err.stack;
throw newErr;
}
There is an new Error Cause proposal for ECMAScript, and it reached stage-4 at TC34!
It means it will be in the next ECMAScript version!
https://github.com/tc39/proposal-error-cause
You would provide the cause as an error option:
throw new Error(`Couldn't parse file at path ${filePath}`, { cause: err });
The ES proposal only formalize it on the language level, but browsers/NodeJS should normally agree to log the full causal chain in practice (see https://github.com/nodejs/node/issues/38725)
As of today (end of 2021), Firefox Devtools are already able to log nested stacktraces!
Joyent released a Node.js package that can be used exactly for that. It is called VError. I paste an example of how you would use the pacakge:
var fs = require('fs');
var filename = '/nonexistent';
fs.stat(filename, function (err1) {
var err2 = new VError(err1, 'stat "%s"', filename);
console.error(err2.message);
});
would print the following:
stat "/nonexistent": ENOENT, stat '/nonexistent'
2021 Update: To chain exceptions in JS:
class MyAppError extends Error {
constructor(...params) {
super(...params)
if (Error.captureStackTrace) {
// This is the key line!
Error.captureStackTrace(this, this.constructor);
}
this.name = this.constructor.name
}
}
See the Mozilla docs on Error.captureStackTrace
Use a try / catch block:
try {
this.config = JSON.parse("}}junkJSON}");
//...etc
}
catch (e) {
//console.log(e.message);//the original error message
e.message = "Your config file is not well formatted.";//replace with new custom message
console.error(e);//raise the exception in the console
//or re-throw it without catching
throw e;
}
http://jsfiddle.net/0ogf1jxs/5/
UPDATE: If you really feel the need for a custom error you can define your own:
function BadConfig(message) {
this.message = message;
this.name = "BadConfig";
}
BadConfig.prototype = new Error();
BadConfig.prototype.constructor = BadConfig;
try {
this.config = JSON.parse("}}badJson}");
} catch(e) {
throw new BadConfig("Your JSON is wack!");
}
http://jsfiddle.net/kL394boo/
Lots of useful info at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
how can I find the error
try {
undef
} catch (e){
console.log(e)
console.dir(e)
}
the information bust be there somewhere, because the console.log (in firebug) includes:
ReferenceError: undef is not defined
but when I browse the e object, I can't find it.
How do I find out what the error is programmatically, so I can handle the error accordingly?
Edit:
try {
if(typeof undef == 'undefined'){
console.log('We should not access this "undef" var');
}
console.log('The next line will produce an exception');
undef
} catch (e){
console.log(e);
for(index in e){
console.log(index+' ('+(typeof e[index])+'): '+ e[index]);
}
}
Which will produce:
We should not access this "undef" var
The next line will produce an exception
ReferenceError: undef is not defined
fileName (string): file:///B:/xampp/htdocs/study/test.html
lineNumber (number): 12
stack (string): #file:///B:/xampp/htdocs/study/test.html:12
I don't think you can pull its type explicitly, but you can test it:
try {
undef
} catch (e){
console.log(e)
console.dir(e)
if(e instanceof ReferenceError) {
console.log("Ooops! Fat fingers!");
}
}
But of trial and error gives me this...
try {
undef
} catch (e){
console.log(e.toString())
// ReferenceError: undef is not defined
}
I guess firebug is just accessing the .toString() method of e
Edit:
I am guessing the .toString() method just concatenates the only two properties that are guaranteed cross browser - name and message - so I think e.message is the only reliable and useful piece of information to go with.