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
Related
This is working !
function rejectedPromise() {
return Promise.reject("ERROR");
}
async function someFunction() {
try {
rejectedPromise()
.catch((err) => console.log(err)); // IT WORKS ! THE ERROR IS BEING LOGGED HERE
}
catch(err) {
console.log(err);
}
}
someFunction();
This is not.
function rejectedPromise() {
return Promise.reject("ERROR");
}
async function someFunction() {
try {
rejectedPromise()
.catch((err) => { throw err; }); // CAN'T I THROW HERE ?
}
catch(err) {
console.log(err); // DOES NOT WORK. THE ERROR SHOULD BE LOGGED HERE
}
}
someFunction();
QUESTION
Why?
Note: my goal is to throw the error from the catch method of the rejected Promise and throw it so it's handled by an outer catch block. Don't know if it matters, but this is happening inside an async function (it doesn't work if I remove the async keyword from the example anyways).
EXTRA:
In Node, I'm getting this (even though there's a catch block):
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)
As pointed out in the comments, there is no need for using .catch() if you are inside an async function. I don't know why you want nested try...catch, but it looks like this would achieve what you want:
function rejectedPromise() {
return Promise.reject("ERROR");
}
async function someFunction() {
try {
try {
await rejectedPromise()
}
catch(err) {
throw err;
}
}
catch(err) {
console.log(err);
}
}
someFunction();
Try to handle every exception in my async code (nodeJS, ExpressJS):
Here is almost pseudo code. I use limiter (npm limiter) module with method removeTokens (num, callback(err,remainingRequest)). Big part of code is inside the callback, and I wanna catch and throw any error there to the handler, but for now the error inside callback is still marked as "unhandled exception" and I don't understand why.
app.post('/', async (req, res) => {
try {
...
return getAll();
async function getAll () {
limiter.removeTokens(1, async (err, remainingRequest) => {
try {
throw new Error('THROWN')
} catch (error) {
throw error
}
})
}
} catch (error) {
console.log(error);
}
});
You shouldn't pass async functions into things that don't expect them (unless you catch all errors, as you are with your app.post callback). Instead, give yourself a wrapper for limiter.removeTokens that returns a promise:
function removeTokens(limiter, id) {
return new Promise((resolve, reject) => {
limiter.removeTokens(id, (err, remainingRequest) => {
if (err) {
reject(err);
} else {
resolve(remainingRequest);
}
});
});
}
(You might also look into util.promisify for that.)
Then:
app.post('/', async (req, res) => {
try {
...
await getAll(); // *** Or you might just use `removeTokens(limiter, 1)` directly here
function getAll() {
return removeTokens(limiter, 1);
}
} catch (error) {
console.log(error);
}
});
Here it is using removeTokens directly:
app.post('/', async (req, res) => {
try {
...
await removeTokens(limiter, 1);
} catch (error) {
console.log(error);
}
});
Firstly if possible please share as much code as you can as then it is easy for us to debug where the problem might be.
Coming you your question i think the problem is that in your try..catch block you are throwing the error instead of handling it with a reject. Below i have pasted a code block which you can try and let me know if it works for you. Please not the syntax might be different but the idea is that you have to reject the Promise in case of error.
`````````limiter.removeTokens(1, async (err, remainingRequest) => {
````````````try {
```````````````throw new Error('THROWN')
````````````} catch (error) {
```````````````return Promise.reject(error) //
````````````}
`````````})
``````}
```} catch (error) {
``````console.log(error);
```}
})
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?
UnhandledPromiseRejectionWarning on async await promise
I have this code:
function foo() {
return new Promise((resolve, reject) => {
db.foo.findOne({}, (err, docs) => {
if (err || !docs) return reject();
return resolve();
});
});
}
async function foobar() {
await foo() ? console.log("Have foo") : console.log("Not have foo");
}
foobar();
Which results with:
(node:14843) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): false
(node:14843) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Note: I know I can solve this issue like this:
foo().then(() => {}).catch(() => {});
But then we are "back" to callbacks async style.
How do we solve this issue?
Wrap your code in try-catch block.
async function foobar() {
try {
await foo() ? console.log("Have foo") : console.log("Not have foo");
}
catch(e) {
console.log('Catch an error: ', e)
}
}
then(() => {}).catch(() => {}) isn't needed because catch doesn't necessarily should go after then.
UnhandledPromiseRejectionWarning means that a promise weren't synchronously chained with catch, this resulted in unhandled rejection.
In async..await, errors should be caught with try..catch:
async function foobar() {
try {
await foo() ? console.log("Have foo") : console.log("Not have foo");
} catch (error) {
console.error(error);
}
}
The alternative is to handle errors at top level. If foobar is application entry point and isn't supposed to be chained anywhere else, it's:
foobar().catch(console.error);
The problem with foo is that it doesn't provide meaningful errors. It preferably should be:
if (err || !docs) return reject(err);
Also, most popular callback-based libraries have promise counterparts to avoid new Promise. It mongoist for mongojs.
Every solution here just silences the error, but you should probably handle the error instead.
How you handle it depends on the error and on what part of the application you're in. Here are some examples.
You're writing an app
If you're writing a node app and something throws, you might want to use process.exit(1) to quit the app and display the error to the user:
async function init() {
await doSomethingSerious();
}
init().catch(error => {
console.error(error);
process.exit(1)
});
You're writing a module
If the code expects an error, you can catch it and use it as a value instead:
module.exports = async function doesPageExist(page) {
try {
await fetchPage(page);
return true;
} catch (error) {
if (error.message === '404') {
return false;
}
// Unrecognized error, throw it again
throw error;
}
}
Notice that this example re-throws the error when it's not the expected one. This is fine. It's the final user’s responsibility to handle network errors:
const doesPageExist = require('my-wonderful-page-checker');
async function init() {
if (await doesPageExist('https://example.com/nope')) {
console.log('All good')
} else {
console.log('Page is missing đź’”')
}
}
// Just like before
init().catch(error => {
console.error(error);
process.exit(1)
});
You're the user
If you're seeing this error when using a prepackaged application via command line, like webpack or babel, it might mean that the application had an error but it was not handled. This depends on the application or your input is not correct. Refer to the application’s manual.
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);
}
});
}