I am trying to convert my old callback style functions to async await. However I can't understand how can I catch unhandled exceptions.
For example let's say I have a function
apiCall(input, function(error, result) {
if (error) {
console.log(error);
} else {
console.log(result);
}
});
I converted to Promise
function test1(input) {
return new Promise(function(resolve, reject) {
apiCall(input, function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
}
Then I call it
test1(4)
.then(function(result) {
console.log('Result: ' + result);
})
.catch(function(errorr) {
console.log('My Error: ' + errorr);
});
Even though I try to return error, sometimes this function crashes. Let's say disk error, JSON parsing error etc. Some error that I didn't handle. I can only catch those errors with
process.on('uncaughtException', function(error) {
console.log('uncaughtException' + error);
});
Is there a way for me to catch all kinds of error with async await?
EDIT: Here is the full github repo for you to try
https://github.com/tosbaha/promise
Run node testme.js and see that it crashes and exception handler doesn't run.
The file that may crash is this Any function may crash but I can't foresee every kind of error. That is why I am looking for a solution to catch an error inside this file.
If you run the code in my repo with node testme.js you will get the following error
results[trackingId] = trackingArray.doesntExist.Something;
^
TypeError: Cannot read property 'Something' of undefined
As you see that catch handler doesn't catch the error.
If apiCall can crash without calling the callback (with an error), I assume it throws some error that can be handled outside it with a try... catch block (although I'm not sure, because I don't know the internal code of apiCall).
You can try the following:
function test1(input) {
return new Promise(function(resolve, reject) {
try {
apiCall(input, function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
} catch (e) {
// reject the errors not passed to the callback
reject(e);
}
});
}
Related
function fails4() {
return new Promise((resolve, reject) => {
setTimeout(function () {
reject(new Error());
}, 100);
});
}
async function myFunc4() {
try {
await fails4();
} catch (e) {
console.log(e);
console.log('that failed', e); //<-- this gets called
}
}
async function loadmYScript() {
try {
await myFunc4();
} catch (error) {
console.log(error);
console.log(123);
}
}
loadmYScript();
cant't execute the console.log(123) as I expected can anybody help me with this question very appreciated
You're calling loadmYScript, which in turn calls myFunc4, which in turn calls fails4. This last one (fails4) throws an error. The error is "catch-ed" by myFunc4. Inside this catch block you don't throw any error, there's only a couple of logs, so the result of loadmYScript is a fulfilled promise with undefined value. It is not rejected because myFunc4 doesn't throw the error.
If you throw an error inside the catch block of myFunc4, you will have your 123 logged, and the promise will be rejected.
I need catch an async exception but i can´t use async/await.
I´m trying to use promises, but it doesn´t work.
An example:
myAsyncFunction().then(function() {
console.log("EVERYTHING OK");
}).catch(function(error) {
console.log(error);
});
function myAsyncFunction() {
return new Promise(function(resolve, reject) {
externalLibraryFunctionAsyncToApiRequest(); //this function throw error
});
}
I can´t modify the externalLibraryFunctionAsynToApiRequest.
Can I do anything to catch a possible exception?
It's not clear what externalLibraryFunctionAsyncToApiRequest actually does. But, if you don't resolve or reject your Promise then nothing is going to come back regardless of success or failure.
You should do something like this:
myAsyncFunction().then(function() {
console.log("EVERYTHING OK");
}).catch(function(error) {
console.log(error);
});
function myAsyncFunction() {
return new Promise(function(resolve, reject) {
try {
throw 'something happend';
// If no error resolve();
} catch (ex) {
reject(ex);
}
});
}
Created a soap api with the node-soap library but when i try to throw a fault using
throw {
Fault: {
Code: {
Value: 'soap:Sender',
Subcode: { value: 'rpc:BadArguments' }
},
Reason: { Text: 'Processing Error' }
}
};
as descibed in the library i get a
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
this is what i am currently doing
ssm.decrypt(args.request, password, base_key)
.then(function (res) {
console.log(res)
parseString(res, async function (err, result) {
if (err) {
//the throws causes the error
throw {
Fault: {
error: {
data: {
error
} //Error object from catch
}
}
};
} else {
//some code
}
thanks
Throwing an error inside the async function
parseString(res, async function (err, result)...
rejects the promise returned by the async function - for which there is no catch handler. If parseString calls its callback synchronously, you could just remove the async declaration leaving the call as
parseString(res, function (err, result)...
If parseString is asynchronous, however, it needs to be promisified so errors can be worked into the surrounding promise chain. As an untested example:
function doParseString( res) {
return new Promise( function( resolve, reject) {
parseSting( res, function( err, result) {
err ? reject( err) : resolve( result);
});
});
}
which could be used along the lines of
ssm.decrypt(args.request, password, base_key)
.then( doParseString)
.then( function (result) {
// some code
})
.catch( console.log); // do something with the error
Thanks, guys for your help but I got the issue
if an async function is been used for the soap api been implemented with node-soap
communication need to be done via callbacks
i changed the throw to
callback({
Fault: {
error: {
data: {
error
}
}
}
});
and it works perfectly
i found it here node-soap doc
I have an async function that grabs the contents of a file, like so:
async function getFile (name) {
return new Promise(function (resolve, reject) {
fs.readFile(`./dir/${name}.txt`, 'utf8', function (error, file) {
if (error) reject(error)
else resolve(file)
})
})
}
And I call that function into a console log
getFile('name').then( console.log )
If I make an error, like misspelling the file name, I get this handy error:
(node:17246) UnhandledPromiseRejectionWarning: Unhandled promise
rejection. This error originated either by throwing inside of an async
function without a catch block, or by rejecting a promise which was not
handled with .catch(). (rejection id: 1)
I can fix it by doing this:
getFile('name').then( console.log ).catch( console.log ) but is there a way to deal with the error within the callback? Perhaps a try catch? How would I do that?
You still need to catch errors that are rejected.
I think it's where you call your getFile function from - that needs to be wrapped in a try/catch block
try {
const result = await getFile('name')
} catch(e) {
... You should see rejected errors here
}
Or, I think this would work for your example:
await getFile('name').then( console.log ).catch(e => {...})
Testing this in the Chrome DevTools console:
async function test () {
return new Promise(function(resolve, reject) {
throw 'this is an error';
})
}
And calling it via the following:
await test().catch(e => alert(e))
Shows that this does, in fact, work!
If I understand correctly, you want your function to resolve regardless of whether you got and error or not. If so you can just resolve in either case:
async function getFile (name) {
return new Promise(function (resolve, reject) {
fs.readFile(`./dir/${name}.txt`, 'utf8', function (error, file) {
if (error) resolve(error)
else resolve(file)
})
})
}
Then you'd need to handle the errors outside, e.g.
getFile('name')
.then(getFileOutput => {
if (getFileOutput instanceof Error) {
// we got an error
} else {
// we got a file
}
})
or
const getFileOutput = await getFile('name');
if (getFileOutput instanceof Error) {
// we got an error
} else {
// we got a file
}
Is that what you're looking for?
I'm using an ID3 tag reader library https://github.com/43081j/id3 & the example function to call is in this format...
id3(this.files[0], function(err, tags) {
console.log(err, tags);
});
It works great for most files but from time to time there is an error like this
Uncaught URIError: URI malformed
I've tried to wrap this function in a try...catch to catch the error like this
try {
id3(file, function(err, tags) {
if (err) throw err;
console.log('tags .. ' + tags);
});
}
catch (e) {
console.log('caught it!');
}
But in fact the error still manages to remain uncaught.
I think it might be to do with the fact that the function is asynchronous, but am really struggling to understand how to prevent this and catch the error.
Ultimately I want to wrap the entire function in a promise, something like this:
return new Promise(function(resolve, reject) {
try {
id3(file, function(err, tags) {
if(err) throw err
resolve(tags);
});
}
catch (err) {
reject('blank');
}
}
but no matter what I try the reject method never gets called on an error.
Thanks!