1
00:00:03,000 --> 00:00:05,704
Now that we've done a bit of refactoring

2
00:00:05,704 --> 00:00:08,882
and extracted this common "fetchJson" function,

3
00:00:09,449 --> 00:00:12,053
it's time to go back to our original goal,

4
00:00:12,053 --> 00:00:13,664
that was to have some more

5
00:00:13,664 --> 00:00:15,710
fine-grained error handling here.

6
00:00:16,332 --> 00:00:19,060
We only want to show a "notFound" page

7
00:00:19,060 --> 00:00:21,930
if the requested product does not exist,

8
00:00:21,930 --> 00:00:24,011
not for every possible error.

9
00:00:24,655 --> 00:00:27,933
So to do that we need to provide more details

10
00:00:27,933 --> 00:00:31,066
about the error that we throw in fetchJson.

11
00:00:31,639 --> 00:00:33,726
And what we're going to do is

12
00:00:33,726 --> 00:00:37,037
create a custom error class called "ApiError",

13
00:00:37,037 --> 00:00:39,917
that needs to extend the built-in Error.

14
00:00:40,561 --> 00:00:42,166
This class needs a constructor,

15
00:00:42,761 --> 00:00:45,103
and here we can pass the "url"

16
00:00:45,103 --> 00:00:46,821
and the "status" code,

17
00:00:46,821 --> 00:00:50,102
because that's the most useful information

18
00:00:50,102 --> 00:00:52,288
about a failed HTTP request.

19
00:00:53,023 --> 00:00:54,715
Now, we need to call "super"

20
00:00:54,715 --> 00:00:57,374
and pass a string, that's the error message.

21
00:00:57,935 --> 00:00:59,531
Here we can show the "url"

22
00:00:59,531 --> 00:01:00,881
and the "status" code.

23
00:01:03,335 --> 00:01:06,133
Next we want to make the "status" available

24
00:01:06,133 --> 00:01:07,500
as a member property,

25
00:01:07,500 --> 00:01:10,624
so we can check the status when an error occurs.

26
00:01:11,255 --> 00:01:13,240
And there are a couple of other things

27
00:01:13,240 --> 00:01:15,748
that we need to do when creating a custom error.

28
00:01:16,301 --> 00:01:18,693
For that I'm going to follow the example

29
00:01:18,693 --> 00:01:19,650
in the MDN docs.

30
00:01:20,210 --> 00:01:23,798
If the browser provides a "captureStackTrace" method

31
00:01:23,798 --> 00:01:25,454
then we need to call it,

32
00:01:26,024 --> 00:01:28,732
and we also need to set the "name" property.

33
00:01:29,232 --> 00:01:30,716
So I'll just copy this bit,

34
00:01:30,716 --> 00:01:32,586
and go and paste it into our code.

35
00:01:35,298 --> 00:01:37,732
But our class is called "ApiError"

36
00:01:37,732 --> 00:01:39,307
and not "CustomError".

37
00:01:40,464 --> 00:01:41,770
I'll also add semicolons.

38
00:01:44,430 --> 00:01:46,870
Ok. Now that we have this "ApiError"

39
00:01:46,870 --> 00:01:49,108
we can throw it from "fetchJson".

40
00:01:49,676 --> 00:01:51,517
But instead of this message,

41
00:01:51,517 --> 00:01:54,017
as arguments we want to pass the "url"

42
00:01:54,017 --> 00:01:55,727
and the "response.status".

43
00:01:56,359 --> 00:01:58,092
And this way we are providing

44
00:01:58,092 --> 00:02:00,244
more detailed information from here.

45
00:02:00,804 --> 00:02:02,232
Now, let's make sure that

46
00:02:02,232 --> 00:02:03,889
what we've done so far works.

47
00:02:05,337 --> 00:02:07,944
Let's try loading a product that doesn't exist

48
00:02:08,443 --> 00:02:10,577
And we get a not found page,

49
00:02:10,577 --> 00:02:12,557
because in the ProductPage

50
00:02:12,557 --> 00:02:15,376
we're still catching all errors here.

51
00:02:16,028 --> 00:02:18,230
Let me comment this out temporarily

52
00:02:18,230 --> 00:02:19,677
and re-throw the error,

53
00:02:20,561 --> 00:02:22,099
so we can see what it looks like.

54
00:02:22,599 --> 00:02:24,560
Ok, it's our "ApiError",

55
00:02:24,560 --> 00:02:27,500
showing the URL and the status code,

56
00:02:27,500 --> 00:02:29,624
that in this case was 404.

57
00:02:30,287 --> 00:02:31,769
At this point we can,

58
00:02:31,769 --> 00:02:34,663
first of all export the "ApiError" class,

59
00:02:35,233 --> 00:02:36,735
then if an error occurs

60
00:02:36,735 --> 00:02:38,628
when getting the product data

61
00:02:39,193 --> 00:02:41,973
we can check if it's an "instanceof"

62
00:02:41,973 --> 00:02:42,977
our ApiError.

63
00:02:44,226 --> 00:02:46,199
And the class should have been auto-imported.

64
00:02:46,699 --> 00:02:47,234
That's fine.

65
00:02:48,699 --> 00:02:50,564
Now, if it is an ApiError

66
00:02:50,564 --> 00:02:53,472
then we can check its "status" property

67
00:02:54,046 --> 00:02:57,287
and only if we received a 404 from the CMS

68
00:02:58,479 --> 00:03:01,490
then we want to show a "notFound" page.

69
00:03:01,990 --> 00:03:04,631
But if it's a different kind of error

70
00:03:04,631 --> 00:03:06,272
we'll just re-throw it,

71
00:03:06,272 --> 00:03:09,769
and let Next.js handle it as an unexpected error.

72
00:03:10,411 --> 00:03:12,428
So if we save these changes

73
00:03:12,428 --> 00:03:15,714
we'll get a not found page for product "99",

74
00:03:15,714 --> 00:03:17,581
because it doesn't exist.

75
00:03:18,230 --> 00:03:20,931
While if we request a valid product "id",

76
00:03:20,931 --> 00:03:22,644
we'll see the normal page.

77
00:03:23,209 --> 00:03:25,435
Ideally we should test what happens

78
00:03:25,435 --> 00:03:27,215
if the CMS is not available,

79
00:03:27,215 --> 00:03:29,440
like we did a couple of videos ago.

80
00:03:29,440 --> 00:03:31,602
But that means rebuilding the app,

81
00:03:31,602 --> 00:03:33,954
run it in production mode, and so on,

82
00:03:33,954 --> 00:03:35,543
so I won't do that again.

83
00:03:35,543 --> 00:03:37,832
But feel free to try it if you like.

84
00:03:38,713 --> 00:03:41,724
What will happen in that case is that

85
00:03:41,724 --> 00:03:44,735
it will be a different kind of error,

86
00:03:44,735 --> 00:03:47,502
so we won't show a not found page,

87
00:03:47,502 --> 00:03:51,082
but Next.js will return a server error page.

88
00:03:51,082 --> 00:03:54,419
Anyway, by creating a custom error class,

89
00:03:54,419 --> 00:03:58,325
we can handle each specific error appropriately.

