JSON.parse, already in try/catch block, still throws syntax error - javascript

parseJsonMsg(msg, jsonCallBack) {
try {
let content = JSON.parse(msg.content);
jsonCallBack(null, content);
} catch (err) {
console.log('[MSG processing ERROR]: ', err.message);
jsonCallBack(err);
}
}
This code is used to log the error whenever it is unable to parse a message.
Apart from logging, this throws syntax error if unable to parse. Why is that so? How can it be handled?
Any advice would be great

I suspect it is the method you are passing in as a parameter that is throwing the error. Make sure jsonCallBack does its own error handling. What is the error you receive?
Errors can be thrown anywhere, including inside catch blocks. If an error is thrown in a catch block it will percolate up the stack until it is either caught or the stack is exhausted and it becomes an uncaught exception.

bit of rewrite
parseJsonMsg(msg, jsonCallBack) {
var err;
var content;
try {
content = JSON.parse(msg.content);
} catch (ex) {
console.log('[MSG processing ERROR]: ', err.message);
err = ex;
}
jsonCallBack(err, content);
}
then as said above, the parse error is forwarded to the caller in jsonCallBack(err)
So it may be the caller which throws the error.
To fix your problem, you should not comment that call jsonCallBack(err) but, depending on the type of caller, bind its error handler then decide what to do.

Related

How to throw an exception with indent?

Is there any way to throw javascript errors and force it to be indented?
Instead of 'Error' to be ' Error'. If not, what can I use instead, that will surely exit my node.js process. Thanks.
You can't modify the way node displays an uncaught error. But, you can catch the error and choose to display it however you want, before exiting your program.
class SpecialError extends Error {}
function main() {
// ...
throw new SpecialError('Whoops!')
}
// This is at the very end, so when the catch finishes,
// there's nothing left to execute, and the program ends.
try {
main()
} catch (err) {
if (!(err instanceof SpecialError)) throw err
console.error([
` Error: ${err.message}`, // Lots of indentation
...err.stack.split('\n').slice(1)
].join('\n'))
// Makes the program exit with status code 1. See here: https://nodejs.org/api/process.html#process_process_exitcode
// Uncomment this when you're in node.
// process.exitCode = 1;
}
I don't know if I realy understood your question, but did you try something like this?
throw new Error('\tSome error message.');

Why can't I catch error thrown from node-postgres?

I'm having an issue catching an error thrown from the Node-Postgres NPM package.
The issue seems simple on the surface, but I've tried everything I can think of.
My code is like the following:
import { Pool } from 'pg' // Import postgres connection pool
const pgPool = new Pool()
async function queryDatabase() {
try {
// Force TypeError by passing undefined
let queryResult = await pgPool.query( undefined )
if ( queryResult.rows.length > 0 ) {
return queryResult.rows[0]
}
return false
} catch( err ) {
// Never Reached
return new Error( 'Test error' )
}
}
queryDatabase()
And the error is as follows:
TypeError: Client was passed a null or undefined query
at Client.query (~/.../node_modules/pg/lib/client.js:479:11)
The error itself is pretty self-explanatory. I'm forcing the error here, for the sake of trying to handle it in the event that undefined gets passed by mistake. I realize that I can simply perform a check to make sure the input is never null or undefined, but that's not my main concern.
My worry is if I can't catch this error thrown from this package, how many other unforeseen cases am I going to encounter where I simply can't catch and handle a thrown error.
I've tried numerous different approaches - The Async/Await Try/Catch method, shown above - I've tried pgPool.query().then().catch() - Combinations of the two. I've even tried running the catch against the Pool instance itself. No matter what I do, I can't handle the exception without using Node's process.on('unhandledRejection', ...), which is of course a bad idea.
I've been racking my brain on this for hours. Is there any way that I can catch and handle errors like this, so it's not crashing my server every time? Thanks in advance!
I was able to reproduce this and it seems to be an actual bug in the pg-library.
According to the source if you call .query on a pool instance, this instance will attempt to connect and get a client. In this connect-callback the actual query is dispatched to the client-module, which will throw the mentioned type error if the query is nil.
This error is thrown synchronously (i.e. the error is not passed to the callback argument, e.g. callback(new TypeError("...")) and since there's no try/catch around the client.query call in the pool's connect-callback, the error will not be caught by your try/catch.
A potential fix would be to wrap the client.query call in a try catch:
client.once('error', onError)
this.log('dispatching query')
try {
client.query(text, values, (err, res) => {
this.log('query dispatched')
client.removeListener('error', onError)
if (clientReleased) {
return
}
clientReleased = true
client.release(err)
if (err) {
return cb(err)
} else {
return cb(undefined, res)
}
})
}catch(err) {
return cb(err)
}
So for now, you probably should create an issue on github and wait for the bugfix or fork the repo and use above workaround, I'm afraid.

Chai / Expect - how to work while developing? Seems really hard to go from expect().to.throw to logging the error

I have this code
expect(function() {
//some error
}).to.throw(Error);
How do I easily go from this to logging the error right here in the test?
Do I really have to type try/catch and console.log? Doesn't that go against the fact that I will need to remove them eventually for the test to pass?
The Chai .toThrow() matcher can be used to ways:
to check of the error throws is of a particular instance
expect(function() {
throw SyntaxError('sample error message');
}).to.throw(SyntaxError);
to check text of the error message
expect(function() {
throw SyntaxError('sample error message');
}).to.throw(/sample error message/);
If this doesn't suite your use-case, you can always try/catch and inspect/make assertions on the object of the caught error:
try {
throw SyntaxError('sample error message');
} catch(e) {
expect(e.message).to.equal('sample error message');
}

Need help on try-catch

I am trying to use try-catch block in my protractor test, please see the code below:
try {
element(by.id('usernameas')).sendKeys(data);
}
catch(err) {
console.log('error occured');
}
I am deliberately passing wrong locator to check whether it is going in catch block or not, currently it is giving me error NoSuchElementError on command prompt and test execution stops rather than going into catch block.
Please suggest.
The call to element(locator).sendKeys returns a promise which is either resolved or rejected. The promise is part of the test's control flow.
The call to element(locator) itself does not throw an error, it is the promise which is rejected.
If you fail to find an element you actually want your entire test to fail, since the scneario cannot be completed.
To get the error message you can use the promise callbacks, as demonstrated below.
Important note: if you handle the promise failure by yourself your test won't fail, so you should better rethrow it
try {
element(by.id('usernameas')).sendKeys(data).then(function() {
console.log('keys sent successfully');
}, function(err) {
console.error('error sending keys ' + err);
throw err;
});
}
catch(err) {
console.log('error occured');
}
The console output is (trimmed):
error sending keys NoSuchElementError: no such element
(Session info: chrome=31.0.1650.63)
(Driver info: chromedriver=2.8.241075,platform=Windows NT 6.1 S .....
I ran into this problem recently and noticed that you DONT need the try/catch block. In Protractor, you can achieve the try/catch like following:
try { <---------------------------- Traditional TRY/CATCH method
loadWebApp();
login();
openUserPreferences();
changePassword();
} catch (err) {
console.error(
"An error was thrown! " + err);
}
loadWebApp().
then(login).
then(openUserPreferences).
then(changePassword).
then(null, function(err) { <----------------- PROTRACTOR equivalent of try/catch
console.error(
"An error was thrown! " + err);
});
Here's the source where I got this info from: https://code.google.com/p/selenium/wiki/WebDriverJs#Promises
under Value Propagation and Chaining
So again, you don't need to explicitly add a try/catch.
In short, the reason this method works is because a promise can either be RESOLVED or REJECTED and in case of a rejected or failed promise, this line [ then(null, function(err) { ... } ] will act as the CATCH block. Also notice that the then(null, function(err))( is NOT taking any callback but only an errBack; so basically, this is saying we don't care about whether the promise gets resolved, we only care about whether it fails and thus the NULL for callback and the function(error) for the errBack. No need to wrap this in a try/catch then throw the error as suggested above by the accepted answer (#Eitan Peer). Hope this helps someone out there struggling with Protractor as I did.

Can syntax errors be caught in JavaScript?

MDN states:
A SyntaxError is thrown when the JavaScript engine encounters tokens or token order that does not conform to the syntax of the language when parsing code.
But if there's a syntax error, how could the program even run in the first place?
How can JavaScript syntax errors even be caught?
You cannot use try-catch blocks to handle syntax errors as they are thrown while the code is being parsed and not while it's running.
However you can use window.onerror and figure out that there's an error. You must ensure that the onerror function is defined in a separate script tag and not in the tag in which the error may be present!
Eg:
This will not work, because the script is yet to start running when the error is thrown:
<script>
window.onerror = function (e) {
console.log('Error: ', e);
};
console.log('a'');
</script>
This will work:
<script>
window.onerror = function (e) {
console.log('Error: ', e);
};
</script>
<script>
console.log('a'');
</script>
jsfiddle demo
In the JS world, SyntaxError CAN be a runtime exception. This can arise, for instance, when trying to parse a JSON response that isn't JSON format. The server can send back lots of types of responses, so if you send a HTML body response to your request that's expecting JSON in the body, you're going to get a SyntaxError thrown in the JS. In such a case, you would get an error message that looks something like this: SyntaxError: JSON Parse error: Unrecognized token '<'.
But there are other runtime SyntaxErrors you could get as well. Mozilla has a list of some here: SyntaxErrors for JSON parsing
You may want to catch these in your code. You can do so with a generic try/catch block like this:
try {
JSON.parse('<html></html>');
} catch (e) {
console.log("I catch & handle all errors the same way.");
}
OR you can look for the SyntaxError specifically:
try {
JSON.parse('<html></html>');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("I caught a pesky SyntaxError! I'll handle it specifically here.");
} else {
console.log("I caught an error, but it wasn't a SyntaxError. I handle all non-SyntaxErrors here.");
}
}
Mozilla has even more info on JS errors and handling them.
It's runtime errors that can be caught with try-catch, not syntax errors (if you eval your code you can handle syntax errors in the evaled code but that's just weird).
I'd recommend you read these:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Statements#try...catch_Statement
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Statements#Exception_Handling_Statements
You can catch programmer-generated and runtime exceptions but you cannot catch JavaScript syntax errors, though you may handle them in some browsers using window.onerror.
This is taken from the book JavaScript- The Complete Reference by Thomas-Powell which I like very much. You can refer to the code examples in that book.
You specifically cannot catch parser-generated SyntaxErrors since they are thrown by the parser, which has no idea what try/catch blocks do. More info on that - Learning how programming languages work
There is a way to catch SyntaxErrors that are generated during code execution. This method is slow, and I would not recommend it. You can catch SyntaxErrors using eval().
var code = `function() {
doSomething()
somethingElse()
var x = 5 + 5
// No ending curly brace` // The code to be run using eval
try {
eval(code) // Try evaluating the code
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
console.log('A SyntaxError has been caught\n\nDetails:\n' + e) // It is a SyntaxError
}
Alternatively, you could use new Function(), which is up to 93% faster - https://jsben.ch/1HLQ1
var code = `function() {
doSomething()
somethingElse()
var x = 5 + 5
// No ending curly brace` // The code to be run using eval
try {
new Function([], code) // Try evaluating the code
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
console.log('A SyntaxError has been caught\n\nDetails:\n' + e) // It is a SyntaxError
}

Categories

Resources