Thus far, you learned a lot about how to handle errors and find out what the state of your application
is.
Now sometimes, you have code which might fail at runtime and you know that but you can't guarantee that
it always works.
In this case you probably want to show a nice screen or at least a custom error message to the user.
Let me show you a constructed example,
let's say that when we render a person class, we actually have a chance of getting an error.
So I will create a random number with math.random and if random is greater than .7, so we get a 30
percent chance, then I will actually throw a new error, something went wrong and this should not be
in the return statement but in the function body.
Now with that, we should sometimes get this error,
let's try this out,
let's save this component and let's toggle persons and it immediately failed.
So we saw this error because we have three components we have a 30 percent chance on each component,
it's not that unlikely.
Sometimes it should succeed though
like in this case
but again, sometimes it will also fail, like here,
something went wrong.
Now of course here this is constructed
but in a real application, you might indeed have some code which run some operation, reaches out to some
web server which can definitely fail and you can't guarantee that it does not. It would
be nice to then at least catch this error and handle it graciously.
For this,
I will create a new component and this is a new feature which was added with react 16,
I'll name it
error boundary because you can create so-called error boundary components there.
I'll name it error boundary there too,
the name is up to you though.
It's called error boundary, the concept but you can name this component whatever you like. Here,
I will create a class error boundary and I will extend component.
So I need to import both react and then with a named import with curly braces component from react,
like that.
So we're creating this component just as we created the app.js component. In there
I want to render something and I will return something,
I will simply return a h1 tag where I say something went wrong, like this.
I only want to return this if we got an error though, so I will add state,
one of the reasons why we have to use a class here and set my state to has error false, I'll also
store error message here which is an empty string.
Now we can add a new property or new method I should say,
componentDidCatch, this is a method which receives potential error and some additional information passed
into it automatically by react and componentDidCatch will be executed whenever a component
we wrap with the error boundary throws an error,
I will show you how to use it in a second,
first of all let's complete the logic here.
In there I want to set the state because we now got an error.
I will set has error to true and I will set error message equal to the error which should be that message.
Now in the render method, we actually have two possible outcomes,
either our state has an error, in this case,
I want to return something went wrong or to be precise,
I can even render the error message.
So this.state.error message or in the else case I return this.props.children,
that's important when accessing prop's in a class component,
you need to add this in the front of it just as you did with state.
So now this.props.children is whatever we wrap inside of error boundary,
this should be our default case but if we get an error thrown by something we wrap inside error boundary,
this method here will fire and hasError will be set
True and hence we can return this.
Now let me simply export a default,
let me export this
error boundary component
and let's now start using it.
I'll use it in the app.js file and wrap my person with it,
so I'll import error boundary from ./errorBoundary, that folder
and in there the error boundary js file, without the file extension as always and let's now wrap our person
with it.
So here in the list where I returned person, there
I actually want to wrap it with error boundary just like that. Also
after the closing tag of person error boundary. Now, error boundary is a so-called higher order component,
it's a component which simply wraps a component with the goal of handling any errors that component
might throw,
in the case of error boundary, that's its job.
Now with that person wrapped with error boundary, we also have to move the key here to the error boundary
because this is now the outer element which we map and the key always has to be on the outer element
in a map method because that's the element we actually replicate.
Now with that let's save it and make sure all files are saved and go back to the application.
Now if you toggle persons until you get an error, you'll still see that error in the middle here unfortunately.
Now that only happens during development mode,
once you've built this for production and ship it to a real server, it will not overwrite your page like
this.
Instead what you will then see is you will see whatever you render inside your error boundary like the
error message or any other default message you have.
This does not mean that you should cluster your whole application with error boundaries, only use them
when it makes sense.
So basically only use them if you have some code you know that it may fail,
don't wrap any other code because if normal code fails, you as a developer probably made a mistake during
development,
only use error boundaries for cases where you know that it might fail and you can't control that.
Then this might be a nice tool for production to show a custom error message and not have the whole
application fail, because the react application will then actually still work fine and only the problematic
component will be replaced with your custom error message.
So error boundary is a nice tool to know, not a tool to use anywhere in your application and therefore
starting with the next module when we dive back into this little example project,
I will also remove it again to not wrap this,
I will also remove my custom error source here to simulate this error.
This is only for this module.