Skip to content

Commit 49dd2dd

Browse files
committed
learn about promise error handling
1 parent 91dfeea commit 49dd2dd

File tree

1 file changed

+134
-2
lines changed

1 file changed

+134
-2
lines changed

Async-JS-Promises-and-Callbacks/README.md

Lines changed: 134 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
| [Multiple Callbacks and setTimeout(0)](#multiple-callbacks-and-settimeout0) |
1010
| [Getting Started with Promises](#getting-started-with-promises) |
1111
| [Chaining Multiple Promises](#chaining-multiple-promises) |
12+
| [Promise Error Handling](#promise-error-handling) |
1213

1314
## Understanding Synchronous Code Execution ("Sync Code")
1415

@@ -384,7 +385,7 @@ Readings:
384385

385386
## Chaining Multiple Promises
386387

387-
Let's now also wrap `navigator.geolocation.getCurrentPosition()` around promise object and then demonstrate the promise chaining.
388+
Let's now also wrap `navigator.geolocation.getCurrentPosition()` around promise object and [`then`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then) demonstrate the promise chaining.
388389

389390
```javascript
390391
const button = document.querySelector('button');
@@ -433,4 +434,135 @@ Readings:
433434

434435
- [JavaScript Promise Chaining](https://www.geeksforgeeks.org/javascript-promise-chaining/)
435436

436-
- [JavaScript Promise Chain - The art of handling promises](https://blog.greenroots.info/javascript-promise-chain-the-art-of-handling-promises)
437+
- [JavaScript Promise Chain - The art of handling promises](https://blog.greenroots.info/javascript-promise-chain-the-art-of-handling-promises)
438+
439+
## Promise Error Handling
440+
441+
Previously, we observed promise chaining in action, and it's important to highlight that you're not limited to returning promises within the chaining sequence. You can return any data, and it will be automatically converted into a promise and wrapped accordingly.
442+
443+
The core concept of promise chaining allows you to execute steps sequentially. For instance, the second step will only trigger once the preceding one, represented by the promise, is resolved. This step is reached when the promise is fulfilled, and anything returned here – which is transformed into a promise if not already – will proceed to the next step. This framework of connecting steps is quite powerful.
444+
445+
Now, let's delve into handling errors, as issues can arise. Consider our previous example where we're obtaining position data and handling errors in our enhanced promise version. In cases such as permissions not being granted(in browser for giving your location), we'd like to elevate the error handling from our prior approach, as we've transitioned to using promises.
446+
447+
```javascript
448+
const button = document.querySelector('button');
449+
450+
const getPosition = (opts) => {
451+
const promise = new Promise((resolve, reject) => {
452+
navigator.geolocation.getCurrentPosition(success => {
453+
resolve(success);
454+
}, error => {
455+
reject(error);
456+
}, opts);
457+
});
458+
return promise;
459+
};
460+
461+
const setTimer = (duration) => {
462+
const promise = new Promise((resolve, reject) => {
463+
setTimeout(() => {
464+
resolve('Done!');
465+
}, duration);
466+
});
467+
return promise;
468+
};
469+
470+
function trackUserHandler() {
471+
let positionData;
472+
getPosition()
473+
.then(posData => {
474+
positionData = posData;
475+
return setTimer(2000);
476+
}, err => {
477+
console.log(err);
478+
})
479+
.then(data => {
480+
console.log(data, positionData);
481+
});
482+
483+
setTimer(1000).then(() => {
484+
console.log('Timer Done!');
485+
});
486+
console.log("Getting position...");
487+
}
488+
489+
button.addEventListener('click', trackUserHandler);
490+
```
491+
492+
This is facilitated using the second argument of the promise constructor's configuration function, specifically the reject parameter. By invoking reject within the error callback, we can funnel our error object into the rejection process. This marks the promise as unsuccessful – not resolved or pending, but in a failed state. Errors are distinctively managed; they don't fit within the regular `then` functions. Rather, `then` accepts two arguments.
493+
494+
The first function handles success when the promise is resolved, while the second argument takes care of failures, situations where the promise doesn't resolve but rejects instead. In our example, the error object is expected as the second parameter of the then method. You're free to name it as needed, and this function can be used for logging the error or performing other operations, such as sending the error data to a server.
495+
496+
By implementing these principles, when you revisit your code and reload the page, you'll notice that if you choose to block geolocation, the corresponding error message appears. The error is captured and presented as part of your code execution.
497+
498+
When working with promises, you might think that adding a second function as an argument takes away some of the benefits promises offer. Even though this second function is not nested, having multiple functions in a row might seem a bit messy. But don't worry, there's a different way to handle this – it's called the [`catch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch) method.
499+
500+
You can use the `catch` method to manage errors in a promise chain. You can put it anywhere in the chain, right after a function that returns a promise, or after any `then` block. Where you place it doesn't really matter.
501+
502+
In our example, you can add the `catch` method after the first `then` block and then continue with another `then` block. Both of these blocks are part of the same promise chain. This is where you can handle errors.
503+
504+
When you use the `catch` method, it works similarly to putting a function as the second argument in a `then` block. It's just another way to handle errors that occur anywhere in the promise chain before the `catch` block.
505+
506+
In a more complex chain, if any promise fails, both approaches will catch the error. But if you have a series of `then` blocks, only the ones after the failed promise will be skipped until you reach a `catch` block or another second argument that handles errors.
507+
508+
Unlike `then` blocks, the `catch` method won't stop the whole chain. It only deals with errors that happened before it. When a promise fails before reaching the `catch` block, the error will be caught in the block and its code will run. However, the next `then` blocks will keep running as usual.
509+
510+
```javascript
511+
const button = document.querySelector('button');
512+
513+
const getPosition = (opts) => {
514+
const promise = new Promise((resolve, reject) => {
515+
navigator.geolocation.getCurrentPosition(success => {
516+
resolve(success);
517+
}, error => {
518+
reject(error);
519+
}, opts);
520+
});
521+
return promise;
522+
};
523+
524+
const setTimer = (duration) => {
525+
const promise = new Promise((resolve, reject) => {
526+
setTimeout(() => {
527+
resolve('Done!');
528+
}, duration);
529+
});
530+
return promise;
531+
};
532+
533+
function trackUserHandler() {
534+
let positionData;
535+
getPosition()
536+
.then(posData => {
537+
positionData = posData;
538+
return setTimer(2000);
539+
})
540+
.catch(err => {
541+
console.log(err);
542+
})
543+
.then(data => {
544+
console.log(data, positionData);
545+
});
546+
547+
setTimer(1000).then(() => {
548+
console.log('Timer Done!');
549+
});
550+
console.log("Getting position...");
551+
}
552+
553+
button.addEventListener('click', trackUserHandler);
554+
```
555+
556+
Where you put the `catch` block determines how it works. To stop the entire promise chain when an error occurs, place the `catch` block at the end of all `then` blocks. This ensures that if a promise fails, the remaining 'then' blocks are skipped and the chain is caught by the `catch` block.
557+
558+
If you put the `catch` block in the middle of the chain, it will catch the error and then the following `then` blocks will run. It won't stop the whole chain, but it's a flexible way to handle errors without crashing your application.
559+
560+
Additionally, the `catch` block lets you return new data. This can be a promise or anything else that will be wrapped in a promise. This works similarly to the `then` method. Any `then` blocks after the `catch` block will run as the promise goes back to being pending after the `catch` block runs.
561+
562+
In short, the `catch` method is a useful way to handle errors in promise chains. Where you put it and how it works lets you manage errors in different ways while still keeping the promise's asynchronous behavior.
563+
564+
Readings:
565+
566+
- [Error handling with promises](https://javascript.info/promise-error-handling)
567+
568+
- [Promise Error Handling](https://www.javascripttutorial.net/es6/promise-error-handling/)

0 commit comments

Comments
 (0)