I want to make a whatapp bot brainly nodejs. And I want to add an argument. my code is like this:
case 'brainly':
const args = process.argv
brainly(args).then(res => {
for(var i=0; i<res.length; i++){
var jawab = res[i].jawaban
client.sendText(from, jawab[0].text)
}
})
break
But, when I run it shows an error like this:
(node:7960) 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().
how to fix this? Please help me.
This means that somewhere in an asynchronous context, most likely inside of the promise created by calling brainly(args), an error occurred, and it wasn't caught and dealt with.
To get started with asynchronous Javascript, I recommend finding some articles about Javascript Promises and Async Functions (that implicitly generate promises, and allow for the await syntax).
There's no real easy way to explain. Javascript is a single-threaded language, but it offers great concurrency through the use of callbacks, promises and the async/await syntax (they all sort of originate from callbacks). Anything that does not happen instantaneously, such as network/disk operations, is asynchronous and must be handled in an appropriate manner. This can be confusing for newcomers as it breaks up the linear asyncronous flow of execution.
Promises are objects that can be created that will either resolve or reject in the future. By calling .then on the promise, you are giving it a callback function that will be called with the resolved value, when it eventually arrives. You should also add a .catch(err => { ... }) handler to the end to deal with errors, which is probably being thrown for some reason as a result of your passed arguments.
Related
I am reading about error handling, and the book says
If a throw occurs inside a Promises then handler function, then it is
a rejection. One way to think about exceptions and rejections is that exceptions are synchronous errors and rejections are asynchronous errors.
Questions
The book writes rejection, but shouldn't that be unfulfilled?
I were under the impression that a throw is always an exception?
And why are exceptions only for synchronous code?
An unfulfilled Promise is simply one that hasn't been fulfilled, which is quite possible even if it doesn't reject. For example:
const prom = new Promise((resolve) => {
// code here that never calls `resolve`
});
That is a Promise that will never be fulfilled - but it won't reject either.
An "unfulfilled" Promise may not necessarily hang forever like the above - it's simply a Promise that hasn't resolved yet.
a throw is always an exception?
To an extent, yes, though it behaves somewhat differently when inside a Promise - it won't cause an error event. Instead, it'll try to find a .catch handler in the Promise chain it's currently in, and if it doesn't find one, an unhandledrejection event will be fired.
And why are exceptions only for synchronous code?
That's just how the language was designed.
I think you need to understand the reason why rejections are needed, the problem it tries to solve. Consider a simple example such as this:
try {
iDoNotExist
} catch(e) {
//e ReferenceError
}
Pretty simple, the code is being evaluated and "tried" for errors. There's such an error and well, it gets caught.
Now, what if we changed it a little bit into this:
try {
setTimeout(function(){ iDoNotExist }, 1000);
} catch(e) {
//e ReferenceError
}
If you run this code, you'll notice that your javascript environment will emit an Error. It's not being caught here. Why? Because the code that throws the error is not being run when it's being "tried", only the setTimeout function which simply schedules the function and well, that function is doing it's job, it's scheduling it correctly. This in turn is the same reason why so many people get it wrong when they try accessing a value that's product of an async function. E.g.
let result;
setTimeout(() => result = true, 1000);
console.log(result) // Why is this undefined? - Famous last question
Enter promises to the rescue, which not only allow you to recover a value which you would typically return, it also lets you recover any potential error that happens on said async operations. Providing you with semantics that are similar with synchronous code (even more when paired with async functions).
So, I would say rejections are complementary to exceptions. To preserve your program flow when there's an asynchronous boundary (just like fulfilled promises do to preserve function composition).
As for what you would call unfulfilled well... there's a couple of things. unfulfilled means "not fulfilled". A rejected promise IS, technically, an unfulfilled promise. However, an unresolved promise (a promise in a pending state) is ALSO an unfulfilled promise. Technically.
Most people will think of the latter but really it could be either. Mostly because it comes from a time where "fulfill" and "resolve" where used interchangeably (which is wrong). But also because that's typically the expected result of a promise resolution.
Under no circumstance is an unresolved promise a rejected promise. An unresolved promise is in a transitory state in which it could transit into either a fulfilled promise or a rejected one.
I have a function which returns a Promise.
Now, sometimes it makes sense for the consumer to use the "then" function on that Promise. But sometimes the consumer simply does not care about when the Promise resolves, and also not about the result - in other words the same function should also be able to be called in a "fire and forget" manner.
So I want these two usage scenarios:
func().then( ... ); // process Promise
func(); // "fire and forget"
This apparently works, but I wonder if this is considered "bad practice", and in particular if this usage pattern could have any unwanted side effects, ie. leading to memory leaks? Right now I am using bluebird, but I consider to switch to native Promises if that makes any difference.
Remember that every call to then results in a new promise. So any Promise implementation that had a memory leak as a result of a promise not having any resolution handlers attached would be a broken implementation, what with all those promises that we never hook handlers to being returned. I very much doubt implementations of ES2015's promises, Bluebird, Q, etc. have that behavior.
Separately, as conceptually a promise's resolution handlers are basically just functions stored by the promise and then called when appropriate, it's not likely to be a memory leak if you never give it any functions to store.
But, there is a problem with your fire-and-forget, just not a memory leak problem: It breaks one of the main Promise rules: Either handle rejection, or return the promise chain to something else that will handle rejection. Since you're not doing that, if the operation fails, you'll have an unhandled rejection. Unhandled rejections are reported to the console and in some environments may terminate your app (at some point, Node.js may start terminating the process when this happens, see this open issue).
If the fact that then returns a new promise is a surprise, consider:
let p1 = new Promise(resolve => {
setTimeout(() => {
resolve('a');
}, 100);
});
let p2 = p1.then(result => {
console.log("p1.then got " + result);
return 'b';
});
p2.then(result => {
console.log("p2.then got " + result);
});
which outputs
p1.then got a
p2.then got b
WebDriverJS and Protractor itself are entirely based on the concept of promises:
WebDriverJS (and thus, Protractor) APIs are entirely asynchronous. All
functions return promises.
WebDriverJS maintains a queue of pending promises, called the control
flow, to keep execution organized.
And, according to the definition:
A promise is an object that represents a value, or the eventual
computation of a value. Every promise starts in a pending state and
may either be successfully resolved with a value or it may be rejected
to designate an error.
The last part about the promise rejection is something I don't entirely understand and haven't dealt with in Protractor. A common pattern we've seen and written is using then() and providing a function for a successfully resolved promise:
element(by.css("#myid")).getAttribute("value").then(function (value) {
// do smth with the value
});
The Question:
Is it possible that a promise returned by any of the Protractor/WebDriverJS functions would not be successfully resolved and would be rejected? Should we actually worry about it and handle it?
I've experienced a use-case of promise rejection while using browser.wait(). Here is an example:
var EC = protractor.ExpectedConditions;
function isElementVisible() {
var el = element(by.css('#myel'));
// return promise
return browser.wait(EC.visibilityOf(el), 1000)
.then(function success() {
return true; // return if promise resolved
}, function fail() {
return false; // return if promise rejected
});
}
expect(isElementVisible()).toBe(true);
expect(isElementVisible()).toBe(false);
Here, if element is on a page, success will be executed, otherwise, if it is not found when 1 second passes, then fail will be called. My first point is that providing a callback for rejection gives an ability to be consistent with what one should expect. In this case I am kinda sure that promise will always resolve to true or false, so I can build a suite relying on it. If I do not provide a fail callback, then I'll get an Uncaught exception because of timeout, which will still fail my particular spec and still run the rest of the specs. It won't be uncaught by the way, Protractor is gonna catch it, but here I want to bring a second point, that Protractor is considered a tool which you use to write and run your code, and if an exception is caught by Protractor, then this exception has left your code unhandled and your code has a leak. But ... at the same time I do not think that one should waste time to catch everything in tests: if there is no element on a page or click has failed, then a respective spec will obviously fail too, which is fine in most of the cases. Unless you want to use the result of failure to build some code on top of it like it is in my sample.
That is the great thing about promises you are going to get a response, either an response of data or an error message. That extended to a series of promises like Webdriver uses you are going to get an array of responses or a failure response of the first one that fails. How you handle the failed response is up to you I usually just dump it into a log for the console to see what failed. The only thing you need to figure out is do you abort the rest of your tests or do you continue on.
Here is a decent article on the subject as well. http://www.toolsqa.com/selenium-webdriver/exception-handling-selenium-webdriver/
Fyi what you are doing is fine you are just never bothering to catch any of the errors though, I am not sure if that matters to you or not, you could also abstract the call in a function to auto handle the errors for you if you wanted to log them somewhere.
I've been using javascript promsises thoughout my angular application but I am tired of repeating the same errorCallback for every promise. I am considering simply wrapping a promise in a try/catch block and having the catch block deal with any promise failures.
Which leads me to asking the question - are the error callbacks redundant if they are in a try/catch block? Will javascript 'catch' the error failure?
Edit: Adding code to reflect how I plan to do this:
try {
$http.post().success(callback);
}(catch)
{
}
The same as:
$http.post().succes(callback()).error(callback)
No, it won't. The reason is that what you are actually doing is queuing your callback function to be invoked when the request gets a successful, asynchronous response. By that time, the execution will have moved past your try/catch block, and you will get an unhandled error.
Another way to look at it is that synchronous, thrown errors immediately propagate up the call tree to the nearest catch block whereas asynchronous error results will only be handlable via the deferred object.
If you wish to invoke the same error handler for multiple promise-based asynchronous operations, you have multiple ways of going about it. The most obvious is injecting $q to your controller and doing something like this:
var deferred1 = $http.get(...);
var deferred2 = someOtherPromiseBasedMethod(...);
$q.all([deferred1, deferred2, ..., deferredN])
.then(null, function (rejection) {
// first failed deferred will provide the rejection value here
});
Another approach is to create a wrapper function:
function handleError(deferred) {
return deferred.then(null, commonErrorHandler);
}
handleError($http.get(...)).then(function (result) {
// Handle the success case here
}
That's still a bit repetitive, but less so, while being more of a declarative approach.
In the Q-promise library, if there is a random problem like TypeError: Cannot read property 'blah' of undefined then it can be handled via the Q.catch() block.
But in Parse-promise library, if there is such a problem inside a then() block, I currently see no way of handling it other than putting a try/catch inside every single then() block!
Am I missing something? What is the q.catch() equivalent for parse promises?
Or are such errors simply impossible to capture without a try/catch block in every then() block?
.then(function(data)){
try{
// do something with data that might throw an exception/error
}
catch(exception){
return Parse.Promose.error(exception);
}
})
As per spec, the .then() function in all Promises/A+ compatible libraries (including the Parse-promise library) takes two callbacks - onFulfilled and a onRejected. If the first argument ie. onFulfilled throws an exception, the promise is rejected and the second argument will be called.
In other words, your example can be rewritten:
.then(function (data) {
// do something with data that might throw an exception/error
}, function (exception) {
// handle the exception
})
In addition, Parse-promises (like many promise libraries) provides additional APIs to make this neater. Specifically, you can use .fail() to wire up callbacks to get called if the promise is rejected.