The catch()
method of a Promise
object schedules a function to be called when the promise is rejected. It immediately returns an equivalent Promise
object, allowing you to chain calls to other promise methods. It is a shortcut for Promise.prototype.then(undefined, onRejected)
.
Try it
Syntax
catch(onRejected)
catch((reason) => {
// rejection handler
})
Parameters
onRejected
-
A
Function
called when thePromise
is rejected. This function has one parameter: the rejection reason.
Return value
Returns a new Promise
. This new promise is always pending when returned, regardless of the current promise’s status. It’s eventually rejected if onRejected
throws an error or returns a Promise which is itself rejected; otherwise, it’s eventually fulfilled.
Description
The catch
method is used for error handling in promise composition. Since it returns a Promise
, it can be chained in the same way as its sister method, then()
.
If a promise becomes rejected, and there are no rejection handlers to call (a handler can be attached through any of then()
, catch()
, or finally()
), then the rejection event is surfaced by the host. In the browser, this results in an unhandledrejection
event. If a handler is attached to a rejected promise whose rejection has already caused an unhandled rejection event, then another rejectionhandled
event is fired.
catch()
internally calls then()
on the object upon which it was called, passing undefined
and onRejected
as arguments. The value of that call is directly returned. This is observable if you wrap the methods.
// overriding original Promise.prototype.then/catch just to add some logs
((Promise) => {
const originalThen = Promise.prototype.then;
const originalCatch = Promise.prototype.catch;
Promise.prototype.then = function (...args) {
console.log("Called .then on %o with arguments: %o", this, args);
return originalThen.apply(this, args);
};
Promise.prototype.catch = function (...args) {
console.error("Called .catch on %o with arguments: %o", this, args);
return originalCatch.apply(this, args);
};
})(Promise);
// calling catch on an already resolved promise
Promise.resolve().catch(function XXX() {});
// Logs:
// Called .catch on Promise{} with arguments: Arguments{1} [0: function XXX()]
// Called .then on Promise{} with arguments: Arguments{2} [0: undefined, 1: function XXX()]
This means that passing undefined
still causes the returned promise to be rejected, and you have to pass a function to prevent the final promise from being rejected.
Because catch()
just calls then()
, it supports subclassing.
Note: The examples below are throwing instances of Error
. As with synchronous throw
statements, this is considered a good practice; otherwise, the part doing the catching would have to perform checks to see if the argument was a string or an error, and you might lose valuable information such as stack traces.
Examples
Using and chaining the catch() method
const p1 = new Promise((resolve, reject) => {
resolve("Success");
});
p1.then((value) => {
console.log(value); // "Success!"
throw new Error("oh, no!");
})
.catch((e) => {
console.error(e.message); // "oh, no!"
})
.then(
() => console.log("after a catch the chain is restored"),
() => console.log("Not fired due to the catch"),
);
// The following behaves the same as above
p1.then((value) => {
console.log(value); // "Success!"
return Promise.reject("oh, no!");
})
.catch((e) => {
console.error(e); // "oh, no!"
})
.then(
() => console.log("after a catch the chain is restored"),
() => console.log("Not fired due to the catch"),
);
Gotchas when throwing errors
Throwing an error will call the catch()
method most of the time:
const p1 = new Promise((resolve, reject) => {
throw new Error("Uh-oh!");
});
p1.catch((e) => {
console.error(e); // "Uh-oh!"
});
Errors thrown inside asynchronous functions will act like uncaught errors:
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
throw new Error("Uncaught Exception!");
}, 1000);
});
p2.catch((e) => {
console.error(e); // This is never called
});
Errors thrown after resolve
is called will be silenced:
const p3 = new Promise((resolve, reject) => {
resolve();
throw new Error("Silenced Exception!");
});
p3.catch((e) => {
console.error(e); // This is never called
});
catch() is not called if the promise is fulfilled
// Create a promise which would not call onReject
const p1 = Promise.resolve("calling next");
const p2 = p1.catch((reason) => {
// This is never called
console.error("catch p1!");
console.error(reason);
});
p2.then(
(value) => {
console.log("next promise's onFulfilled");
console.log(value); // calling next
},
(reason) => {
console.log("next promise's onRejected");
console.log(reason);
},
);
Specifications
Specification |
---|
ECMAScript Language Specification # sec-promise.prototype.catch |
Browser compatibility
BCD tables only load in the browser
See also
Improve Article
Save Article
Improve Article
Save Article
This article covers the use of reject and throw premises in Javascript and explains it’s differences.
reject(): It is an inbuilt function in Javascript that returns a Promise object which has been rejected for a particular given reason.
Syntax:
Promise.reject(reason)
Examples: The reason can be a simple string message or you can even pass an Error object.
- Program 1: Passing a string message as the reason.
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
reject(
'promise failed!'
);
});
p.
catch
(err => {
console.log( err );
});
</script>
- Output:
promise failed!
- Program 2: Passing an instanceOf Error as reason.
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
reject(
new
Error(
'promise failed!'
) );
});
p.
catch
( err => {
console.log( err );
});
</script>
- Output: As you can see when we are passing an Error object we get the entire Error tree. So it is upto the user which one the user prefers.
Error: promise failed! at :4:9 at new Promise () at :2:11 at render (tryit.php:202) at tryit.php:170 at dispatch (jquery.js:4435) at r.handle (jquery.js:4121)
throw: It is used in JavaScript to create and throw user defined exceptions. Using JavaScript throw statement, you can completely control program flow and generate the user define error messages. If we use throw instead of reject() in the above two examples the results will be exactly same (you can try it yourself just by replacing reject with throw).
Examples: However throw can be used in any Javascript try-catch block and not only with promises.
- Program 1: Using throw in a promise.
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
throw
(
'promise failed!'
);
});
p.
catch
(err => {
console.log( err );
});
</script>
- Output:
promise failed!
- Program 2: Using throw without a promise.
javascript
<script>
var
a = 20;
try
{
if
( a < 25 )
throw
(
'Less than 25'
);
console.log(
'Okay!'
);
}
catch
(err)
{
console.log( err );
}
</script>
- Output: Now as we have understood the basic working of both reject and throw, let us talk about the differences between them:
Less than 25
Comparison between Promise- reject and throw:
1. If there is an asynchronous callback function inside the Promise then we cannot use throw from inside the callback function as it will not be recognised by catch() and we will be getting an error in the output.
- Program 1:
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
setTimeout( () => {
throw
(
'promise failed!'
);
}, 1000);
});
p.
catch
( ( err )=> {
console.log( err );
});
</script>
- Output: As you can see the error message (“promise failed!”) has been printed in the output but it wasn’t printed by the catch() function of our promise. It becomes an uncaught exception.
/home/akarshan/Desktop/Projects/Personal/gfg/app.js:3 throw( 'promise failed!' ); ^ promise failed! (Use `node --trace-uncaught ...` to show where the exception was thrown)
- Program 2: To resolve the above situation we can make use of reject() method.
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
setTimeout( () => {
reject(
'promise failed!'
);
}, 1000);
});
p.
catch
( (err) => {
console.log( err );
});
</script>
- Output: Here the catch block is able to recognise reject() and print the corresponding message.
promise failed!
2. This is a very basic difference. If throw is encountered anywhere inside a function the exception is thrown immediately and the control flow is terminated.In other words after throwing the exception control comes out of the function inside which the exception was thrown.
- Program 1:
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
throw
(
'promise failed!'
);
console.log(
"Here"
);
});
p.
catch
( err => {
console.log( err )
});
</script>
- Output: From this example it is clear that the statement console.log(“Here”) is not getting executed.
'promise failed!'
- Program 2: To resolve above situation we use reject() instead of throw the statements after the reject statement inside the function will get executed before the control goes to the catch block.
javascript
<script>
const p =
new
Promise( ( resolve, reject ) => {
reject(
'promise failed!'
);
console.log(
"Here"
);
});
p.
catch
( err => {
console.log( err )
});
</script>
- Output:
Here promise failed!
3. The reject can only be used with a Javascript promise but throw unlike reject can be used to create and throw user-defined exceptions in any try-catch block and not only the ones with promises. If you use Promise.reject() in a try-catch block which is not associated with a promise, UnhandledPromiseRejectionWarning error will pop up.
- Program 1:
javascript
<script>
var
a=20;
try
{
if
( a < 25 )
Promise.reject (
'Less than 25'
);
console.log(
'Okay!'
);
}
catch
(err)
{
console.log(
"inside catch"
);
console.log( err );
}
</script>
- Output: Here, UnhandledPromiseRejectionWarning error comes as Promise.reject() cannot find a catch block associated with a Promise object.
Okay!
- Program 2: The catch block in the above code is not associated with any Promise object and so it is not executed. This is clear from the output as the message “inside catch” is not getting printed. But if we use throw this error will not occur.
javascript
<script>
var
a=20;
try
{
if
( a < 25 )
throw
(
'Less than 25'
);
console.log(
'Okay!'
);
}
catch
(err)
{
console.log(
"inside catch"
);
console.log( err );
}
</script>
- Output:
inside catch Less than 25
JavaScript promises allow asynchronous code to use structured error handling. The promise chains are served as a great way of error handling.
Whenever a promise rejects, the control jumps to the nearest rejection handler.
One of the most useful methods of error-handling is .catch.
As it was already mentioned, .catch is one of the most useful methods for error handling in JavaScript.
Let’s view a case, in which the URL to fetch is wrong (no such site), and the .catch method handles it:
Javascript promise fetch is wrong and .catch method
fetch(‘https://noSuchServer.someText’) // rejects
.then(response => response.json())
.catch(err => console.log(err)) // TypeError: failed to fetch (the text may vary)
But note that .catch is not immediate. It might appear after one or several .then.
Everything might be correct with the site, but the response is not valid JSON.
The simplest way of catching all the errors is to append .catch to the end of the chain. Here is an example:
Javascript promise fetch is wrong and .catch method
fetch(‘/promiseChaining/user.json’)
.then(response => response.json())
.then(user => fetch(`https://api.github.com/users/${user.name}`))
.then(response => response.json())
.then(user => new Promise((resolve, reject) => {
let img = document.createElement(‘img’);
img.src = user.avatarUrl;
img.className = «promiseAvatarExample»;
document.body.append(img);
setTimeout(() => {
img.remove();
resolve(user);
}, 3000);
}))
.catch(error => console.log(error.message));
Usually, .catch doesn’t trigger. But, in case any of the promises, as mentioned earlier, rejects, it will catch it.
There is an invisible try..catch around the code of a promise handler and promise executor. In case of an exception, it will be treated as a rejection.
It is shown in the following code:
new Promise((resolve, reject) => {
throw new Error("Error!!");
}).catch(console.log); // Error: Error!!
It operates the same as this code:
Javascript try..catch
new Promise((resolve, reject) => {
reject(new Error(«Error!!»));
}).catch(console.log); // Error: Error!!
The invisible try..catch will catch the error and transform it into a rejected promise. It can happen both in the executor function and its handlers. In case you throw inside a .then handler, it means a rejected promise, and the control jumps to the closest error handler.
An example will look like this:
Javascript try..catch
new Promise((resolve, reject) => {
resolve(«Yes»);
}).then((result) => {
throw new Error(«Error!!»); // rejects the promise
}).catch(console.log); // Error: Error!!
That may happen to all the errors, not just ones caused by the throw statement.
We can consider a programming error as an example:
Javascript throw statement
new Promise((resolve, reject) => {
resolve(«Yes»);
}).then((result) => {
someFunction(); // no such function
}).catch(console.log); // ReferenceError: someFunction is not defined
The final .catch will catch both explicit rejections and accidental errors in the handlers.
As it was already stated, .catch at the end of the promise chain is equivalent to try..catch. You may have as many .then handlers as you like, then use a single .catch at the end of the chain for handling all the errors.
The regulartry..catch allows you to analyze an error and rethrow it if it can’t be handled. A similar situation is possible for promises.
If you throw inside .catch, then the control will go to the next nearest error handler. If you handle the error and finish normally, it will continue to the next nearest successful .then handler.
The example below illustrates the successful error-handling with .catch:
Javascript error-handling with .catch
// the execution: catch -> then
new Promise((resolve, reject) => {
throw new Error(«Error!!»);
}).catch(function (error) {
console.log(«The error-handling, continue normally»);
}).then(() => console.log(«The next successful handler runs»));
In the example above, the .catch block finishes normally. Hence, the next effective .then is called.
Now let’s check out another situation with .catch. The handler (*) catches the error but is not capable of handling it:
Javascript error-handling with .catch console.log
// the execution: catch -> catch -> then
new Promise((resolve, reject) => {
throw new Error(«Error!!»);
}).catch(function (error) { // (*)
if (error instanceof URIError) {
// handle
} else {
console.log(«Can’t handle such a error»);
throw error; // throwing this or that error jumps to the next catch
}
}).then(function () {
/* doesn’t run here */
}).catch(error => { // (**)
console.log(`The unknown error: ${error}`);
// do not return anything => execution goes the usual way
});
The execution jumps from the initial .catch (*) to the following one down the chain.
In this section, we will examine the cases when errors are not handled.
Let’s see that you have forgotten to append .catch to the end of the chain.
Here is an example:
new Promise(function () {
noSuchFunc(); // Error here, no such function
})
.then(() => {
// successful promise handlers
}); // no append .catch at the end
If there is an error, the promise will be rejected. The execution will jump to the nearest rejection handler. But there exists none, and the error will get “stuck”.There isn’t any code for handling it.
So, what will happen if an error is not caught by try..catch? The script will collapse with a console message. Things like that occur with unhandled promise rejections.
The engine of JavaScript usually tracks this kind of rejections, generating a global error.
For catching such errors in the browser, you can use the event unhandledRejection, as follows:
window.addEventListener('unhandledRejection', function (event) {
// the event object has two special properties
console.log(event.promise); // [object Promise] - error
console.log(event.reason); // Error: Error!! - the unhandled error
});
new Promise(function () {
throw new Error("Error!!");
}); // no catch to handle the error
So, in case there is an error, and no .catch can be found, the unhandledRejection will trigger getting the event object with the information regarding the error.
As a rule, this kind of errors are unrecoverable. The most proper solution in such circumstances is to inform the user about it, reporting the incident to the server.
Non-browser environments, such as Node.js, include other options for tracking unhandled errors.
One of the most significant assets of using promises is the way they allow you to handle errors.
Errors in the promises can be handled with .catch: no matter it’s a reject() call or an error thrown in a handler. It would be best if you put .catch precisely in the places where you want to handle errors. The handler analyzes the errors rethrowing the ones that are unknown (for example, programming mistakes).
In any other case, you need to have unhandledRejection event handler ( for browsers and analogs of different environments). It will track unhandled errors informing the user about them. It will help you avoid the collapse of your app.
Summary: in this tutorial, you will learn how to deal with error handling in promises.
Suppose that you have a function called getUserById()
that returns a Promise:
Code language: JavaScript (javascript)
function getUserById(id) { return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
Normal error
First, change the getUserById()
function to throw an error outside the promise:
Code language: JavaScript (javascript)
function getUserById(id) { if (typeof id !== 'number' || id <= 0) { throw new Error('Invalid id argument'); } return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
Second, handle the promise by using both then()
and catch()
methods:
Code language: JavaScript (javascript)
getUserById('a') .then(user => console.log(user.username)) .catch(err => console.log(err));
The code throws an error:
Code language: JavaScript (javascript)
Uncaught Error: Invalid id argument
When you raise an exception outside the promise, you must catch it with try/catch
:
try { getUserById('a') .then(user => console.log(user.username)) .catch(err => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); }
Code language: JavaScript (javascript)
Output:
Code language: JavaScript (javascript)
Caught by try/catch Error: Invalid id argument
Errors inside the Promises
We change the getUserById()
function to throw an error inside the promise:
Code language: JavaScript (javascript)
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { throw new Error('Unauthorized access to the user data'); } resolve({ id: id, username: 'admin' }); }); }
And consume the promise:
Code language: JavaScript (javascript)
try { getUserById(10) .then(user => console.log(user.username)) .catch(err => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); }
Output:
Code language: JavaScript (javascript)
Caught by .catch Error: Unauthorized access to the user data
If you throw an error inside the promise, the catch()
method will catch it, not the try/catch.
If you chain promises, the catch() method will catch errors that occurred in any promise. For example:
Code language: JavaScript (javascript)
promise1 .then(promise2) .then(promise3) .then(promise4) .catch(err => console.log(err));
In this example, if any error in the promise1, promise2, or promise4, the catch()
method will handle it.
Calling reject()
function
Throwing an error has the same effect as calling the reject()
as illustrated in the following example:
Code language: JavaScript (javascript)
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('Unauthorized access to the user data'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)) .catch(err => console.log(`Caught by .catch ${err}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); }
In this example, instead of throwing an error inside the promise, we called the reject()
explicitly. The catch()
method also handles the error in this case.
Missing the catch() method
The following example does not provide the catch()
method to handle the error inside the promise. It will cause a runtime error and terminate the program:
Code language: JavaScript (javascript)
function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('Unauthorized access to the user data'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)); // the following code will not execute console.log('next'); } catch (error) { console.log(`Caught by try/catch ${error}`); }
Output:
Uncaught (in promise) Unauthorized access to the user data
If the promise is resolved, you can omit the catch()
method. In the future, a potential error may cause the program to stop unexpectedly.
Summary
- Inside the promise, the
catch()
method will catch the error caused by thethrow
statement andreject()
. - If an error occurs and you don’t have the
catch()
method, the JavaScript engine issues a runtime error and stops the program.
Was this tutorial helpful ?
Back to: JavaScript Tutorial For Beginners and Professionals
JavaScript Promise Error Handling with Examples
In this article, I am going to discuss JavaScript Promise Error Handling with Examples. Please read our previous article where we discussed JavaScript Promise.race() vs Promise.all() in detail.
JavaScript Promise Error Handling
Promise chains are good at error handling. When a promise rejects, the control jumps to the closest rejection function. Errors thrown from promises are handled by the second parameter (reject) passed to then() or by the handler passed to catch()
.then(null, error => { /* handle error here */ });
// or
foo().catch(error => { /* handle error here */ });
Synchronously throwing an error from function that should return a promise
Imagine a function below like this:
<html> <head> <title>JavaScript Promise error Handling example</title> </head> <body> <script> function foo(arg) { if (typeof arg != 'number' || arg <= 0) { throw new Error('Invalid arg argument') } return new Promise((resolve, reject) => setTimeout(() => resolve(arg + ' ' + 'completed'), 1000) ) } foo('fdfd') .then(result => console.log(result)) .catch(err => console.log(err)) // <-- Error: Invalid argument will be caught here </script> </body> </html>
Output:
In the above example foo() function throw an error outside the promise, which gets handled by using both then() and catch() methods.
Raise an exception outside the promise
When we raise an exception outside the promise, we must catch it with try/catch.
<html> <head> <title>JavaScript Promise error handling with try catch example</title> </head> <body> <script> function foo(arg) { if (typeof arg != 'number' || arg <= 0) { throw new Error('Invalid arg argument') } return new Promise((resolve, reject) => setTimeout(() => resolve(arg + ' ' + 'completed'), 1000) ) } try { foo('alphnumberic') .then(result => console.log(result)) .catch(err => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); } </script> </body> </html>
Output:
Throw an error inside the Promises
Inside the promise, the catch() method will catch the error caused by the throw statement and reject(). We have modified the existing function so as to throw an error inside the promises and then consume the promise.
<html> <head> <title>JavaScript throw an error inside the Promises example</title> </head> <body> <script> let isValid = false; function foo(arg) { return new Promise((resolve, reject) => { if (!isValid) { throw new Error('Invalid argument is passed to function') } setTimeout(() => resolve(arg + ' ' + 'completed'), 1000) }) } try { foo('alphnumberic') .then(result => console.log(result)) .catch(error => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); } </script> </body> </html>
Output:
If we throw an error inside the promises the catch() method will catch the error, not by the try/catch.
Calling reject() method of Promise inside the promise
reject() method returns a promise that is rejected. It is highly used for debugging purposes and error catching. We have modified the existing function so as to throw an error by calling reject() method. As throwing an error has the same impact as calling the reject() method that has elaborated in the below example:
<html> <head> <title>JavaScript throw an error by calling reject() method example</title> </head> <body> <script> let isValid = false; function foo(arg) { return new Promise((resolve, reject) => { if (!isValid) { reject('Invalid argument is passed to function') } setTimeout(() => resolve(arg + ' ' + 'completed'), 1000) }) } try { foo('alphnumberic') .then(result => console.log(result)) .catch(error => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); } </script> </body> </html>
Output:
In the above example rather than throwing an error inside the promise, we have called the reject() method of promise explicitly. In this case catch() method also handles the error as it handles in throwing an error inside the promises.
Unhandled rejected by missing the catch() method
An error will be silently ignored if a promise doesn’t have a catch() block or reject() handler. If any error occurs and we don’t have the catch() method, the JavaScript engine issues a runtime error and stops the execution of the program.
<html> <head> <title>JavaScript missing the catch()method example</title> </head> <body> <script> let isValid = false; function foo(arg) { return new Promise((resolve, reject) => { if (!isValid) { reject('Invalid argument is passed to function') } setTimeout(() => resolve(arg + ' ' + 'completed'), 1000) }) } try { foo('alphnumberic') .then(result => console.log(result))//this will not execute //.catch(error => console.log(`Caught by .catch ${error}`)); } catch (error) { console.log(`Caught by try/catch ${error}`); } </script> </body> </html>
Output:
Chaining a Promise
If we have a promise chain then an error occurred in any promises, the catch() method will catch it.
<html> <head> <title>JavaScript error handing chaining a promise example</title> </head> <body> <script> function foo(arg) { return new Promise((resolve, reject) => { if (typeof arg === 'undefined') { throw new Error('Invalid argument is passed to function') } setTimeout(() => resolve(arg + ' ' + 'completed'), 1000) }) } foo('dsds') //promise1 .then(result => foo()) //promise2 .then(result => foo('dsds')) //promise3 .then(result => foo('dsds')) //promise4 .catch(error => console.log(`Caught by .catch ${error}`)); </script> </body> </html>
Output:
In the above example if any error occurred in Promise1, promise2, promise3, or promise4 then it will catch by catch() method.
In the next article, I am going to discuss JavaScript Async Await with Examples. Here, in this article, I try to explain the JavaScript Promise Error Handling with Examples. I hope this JavaScript Promise Error Handling with Examples article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this JavaScript Promise Error Handling.
Последнее обновление: 30.08.2021
Одним из преимуществ промисов является более простая обработка ошибок. Для получения и обработки ошибки мы можем использовать
функцию catch() объекта Promise
, которая в качестве параметра принимает функцию обработчика ошибки:
const myPromise = new Promise(function(resolve, reject){ console.log("Выполнение асинхронной операции"); reject("Переданы некорректные данные"); }); myPromise.catch( function(error){ console.log(error); });
Функция catch() в качестве параметра принимает обработчик ошибки. Параметром этой функции-обработчика является то значение,
которое передается в reject()
.
Консольный вывод:
Выполнение асинхронной операции Переданы некорректные данные
Генерация ошибки
Выше для извещения о возникшей ошибке вызывалась функция reject()
. Но стоит отметить, что ошибка может возникнуть и без вызова функции
reject()
. И если в выполняемой в промисе операции генерируется ошибка в силу тех или иных причин, то вся операция также завершается ошибкой.
Например, в следующем коде вызывается нигде не определенная функция getSomeWork()
:
const myPromise = new Promise(function(resolve){ console.log("Выполнение асинхронной операции"); getSomeWork(); // вызов не существующей функции resolve("Hello world!"); }); myPromise.catch( function(error){ console.log(error); });
Поскольку функция getSomeWork()
нигде не объявлена, то выполнение асинхронной задачи завершится ошибкой и не дойдет до вызова resolve("Hello world!")
.
Поэтому сработает функция обработки ошибок из catch()
, которая через параметр error получит информацию о возникшей ошибке, и
в консоли браузера мы увидим сообщение об ошибке:
Выполнение асинхронной операции ReferenceError: getSomeWork is not defined at index.html:39 at new Promise (<anonymous>) at index.html:37
throw
Также ошибка может быть результатом вызова оператора throw, который генерирует ошибку:
cconst myPromise = new Promise(function(resolve, reject){ console.log("Выполнение асинхронной операции"); const parsed = parseInt("Hello"); if (isNaN(parsed)) { throw "Not a number"; // Генерируем ошибку } resolve(parsed); }); myPromise.catch( function(error){ console.log(error); });
Здесь парсится в число случайная строка. И если результат парсинга не представляет число, то с помощью оператора throw
генерируем ошибку.
Это придет к завершению всей функции с ошибкой. И в итоге результат будет обработан функцией catch
:
Выполнение асинхронной операции Not a number
В этом случае функция обработчика получает сообщение об оошибке, который указывается после оператора throw
.
Данная ситуация может показаться искуственной, так как нам нет смысла генерировать в коде выше ошибку с помощью throw, поскольку в этом случае мы также
можем передать сообщение об ошибке в функцию reject:
if (isNaN(parsed)) { reject("Not a number"); }
Однако данный оператор может применяться во внешней функции, которую мы вызываем в коде:
function getNumber(str){ const parsed = parseInt(str); if (isNaN(parsed)) throw "Not a number"; // Генерируем ошибку else return parsed; } const myPromise = new Promise(function(resolve){ console.log("Выполнение асинхронной операции"); const result = getNumber("hello"); resolve(result); }); myPromise.catch( function(error){ console.log(error); });
Здесь парсинг строки в число вынесен во внешнюю функцию — getNumber
, однако при вызове этой функции в промисе, также из оператора throw возникнет ошибка.
И соответственно будет выполняться функция catch()
, где роизойдет обработка ошибки.
try..catch
Как и в общем случае, операции, которые могут генерировать ошибку, можно помещать в конструкцию try..catch
, а при возникновении исключения в блоке catch вызывать функцию reject()
:
const myPromise = new Promise(function(resolve, reject){ try{ console.log("Выполнение асинхронной операции"); getSomeWork(); // вызов не существующей функции resolve("Hello world!"); } catch(err){ reject(`Произошла ошибка: ${err.message}`); } }); myPromise.catch( function(error){ console.log(error); });
Консольный вывод:
Выполнение асинхронной операции Произошла ошибка: getSomeWork is not defined
Обработка ошибки с помощью функции then
Кроме функции catch
для получения информации об ошибке и ее обработки также можно использовать функцию
then() — ее второй параметр представляет обработчик ошибки, который в качестве параметра получает переданное из функции
reject
значение:
promise .then(function(value){ // получение значения }, function(error){ // обработка ошибки });
Второй параметр функции then()
представляет функцию обработчика ошибок. С помощью параметра error
в функции-обработчика мы можем получить переданное в reject()
значение, либо информацию о возникшей ошибке.
Рассмотрим следуюший пример:
function generateNumber(str){ return new Promise(function(resolve, reject){ const parsed = parseInt(str); if (isNaN(parsed)) reject("значение не является числом") else resolve(parsed); }) .then(function(value){ console.log("Результат операции:", value);}, function(error){ console.log("Возникла ошибка:", error);}); } generateNumber("23"); generateNumber("hello");
В данном случае для того, чтобы в промис можно было передать разные данные, он определен как возващаемый результат функции generateNumber()
. То есть в данном случае консольный вывод будет следующим:
Результат операции: 23 Возникла ошибка: значение не является числом