You can find a summary of the code updates in this pull request . Read on for explanation.
1. try/catch block
First, let’s implement a try/catch block for any errors that are thrown in the normal course of business (for example, by the response.json()
statement).
Then, if any statement within the try
block throws an error, we’ll go straight to the catch
block (without finishing the rest of the try
block after the error). So we’ll register in the catch
block that we’ve seen an error, by setting status
to “error”.
page.tsx
2. Store error in state
When we create an ErrorCard
UI in a future workshop, we’re going to need a string version of the error
exception from the catch
block. We’ll use the the toString() method to get a string, and store it in a new error
state.
Any time we start a new fetch call, we’ll reset the error
to undefined
, for a clean slate.
page.tsx
You may have seen a complaint from TypeScript here, that error
is of type unknown
:
It’s true! in JavaScript you don’t have to throw
an Error
instance – if you want, you could, say, throw the number 8
(I wouldn’t advise it, but it’s allowed). To satisfy TypeScript, we’ll need to use optional chaining here, just in case the error
value doesn’t have a toString()
method.
3. More errors
There are a couple situations where we’d want to deliberately throw an error:
- if response.ok is falsy
- if
json
doesn’t have aquote
property
In either of these cases, we can throw an Error and it will be handled by the catch
block. The argument to Error
will show up in the error?.toString()
value.
- For the
!response.ok
condition, we can get an error description in response.statusText , so we’ll use that as the argument to the thrownError
. - For the
json
error, we’ll use a static error string of “Malformed response”.
page.tsx
4. Examining state
Let’s add another console.log
to the Home
component in page.tsx, so we can see the error
state value as well:
page.tsx
Then we can do things in src/app/api/get-quote-styles/route.ts to throw errors. Let’s start by throwing an error in the handler:
route.ts
Here, after clicking the button, ok
is false. We get response.statusText as the
error` value, which in this case is “Internal Server Error”. (If we wanted to get the “kablooie” string on the client, we’d need to handle the error on the server and send the error string via JSON along with a 500 status. That’s outside the scope of this workshop.)
We can trigger the “Malformed response” error by changing the property name (to, say someOtherProperty
). Since json
doesn’t have a quote
property anymore, json?.quote
is undefined
, which is falsy. This means the !json?.quote
condition will evaulate to true
, and the “Malformed response” error will be thrown.
route.ts
Up next
In the next workshop, we’ll move the state and fetch call to a custom hook. This way, someone reading the Home
component can get a big-picture view without having to read all the details of the logic.