Okay guys.
So let's do a throwback to when we implemented error handling in the first project.
So a quick reminder of how the errors work in PHP.
Now obviously you are talking about that because this video is about error handling.
So in PHP you've got two kinds of errors.
One is when there is an error that is not an exception, and the other is when there is a thrown exception
that is unhandled anywhere else.
Now this exists for legacy reasons because before exceptions you only had errors.
So to handle errors or to customize the way it's handled, which you typically would like to do, and
all the PHP frameworks do that, you need to register two functions or two callbacks.
That would be one for handling exceptions and one for handling errors.
And this would be what I'd like to do in this video.
At least I'd like to begin, because we're gonna make it a little bit more better.
So, uh, to just get straight to the point, we'd like to create an error handler class that will handle
both the exceptions and errors, but also will recognize whether we are currently running inside the
web server environment or inside the command line.
Why is that?
Because on the web server, you'd like to display an error page with different amount of information
depending if we are in a debug mode or production mode, and in the command line you'd like to display
the error message in the command line, you would not like to render a page, and additionally on top
of that.
In all cases, we'd like to log something to the error log, and this time we won't be logging everything
directly to the CLI output.
We'd like to store the error logs to a file so that it can be later reviewed.
Okay, so without further ado, let's jump into implementing this in our current project.
So let me begin with creating the new file.
Now that's a core feature.
So we are creating a file inside the core namespace.
This would be called error handler.
And it's going to be handling all types of errors.
Now let's define the core namespace and the class name.
That's an error handler.
So the most generic Function that we need.
Here is the handle exception one.
Now you're going to see why.
So I've said that we need to handle both.
Exceptions and errors that are not exceptions.
But we can do a simple trick so that everything goes through this single handle exception method.
It accepts an argument of type throwable, which is something more generic than an exception.
This is an exception.
And let me add another one.
So this would be public static function.
Handle error.
Now this needs some specific attributes like the error level the message the file.
It happened in and on which line.
Okay.
So we're going to use this method to register non exception errors handling.
But what I'm going to do here is I'm just going to create a new error exception.
And I'm just going to pass all those parameters to it.
So this would be a message.
Let's just set the default code of zero.
Then we're going to pass the level.
As you can see I'm just passing exactly the parameters that the constructor of this exception expects.
So there is also the file name.
And the last is the line exactly as the parameters on this exception okay.
So I'm creating a new exception.
And instead of throwing it I just call handle Exception.
Passing the exception.
That way, this is the only place where we need to implement the actual logic of what needs to happen
with any kind of errors.
So what needs to happen here is first we need to log the error.
And this means just log it to whatever is configured as the current logger, whether this is the output
directly in the terminal or stored in a file.
We're going to be handling that later.
And next step is to see what environment we are currently in.
So in PHP there is a function called PHP sub name.
If this is CLI this means we are in a command line environment.
And this would not include a up will be built in server which you start through command line.
This only means scripts that are being run directly when you type, like in our case we do PHP binary.
Let's say load schema PHP and if that's the case we're gonna call a method.
Or maybe I can use just static.
And this would be render CLI error passing the exception.
Otherwise it means we have a server error on a web server, which means we need to render an error page
which we also pass the exception.
Now obviously those methods don't exist.
We're gonna implement them next.
Okay.
Next thing I'd like us to work on is formatting of the error message.
For that, let's define a private.
Private static method that will be called format error message.
And this one responsibility is to convert the exception into a string with an error message with the
given format.
And this will be used both to output the error on the CLI and on the website.
And this accepts the variable which is exception and string which would be a format.
This just means we need different formats of output on the website and on the CLI, specifically on
the website.
We just might want to produce a text error that's a string, but on the CLI we've got more options.
We can, for example add some colors For it to be more distinguishable, that it isn't actually an error.
And that's why we're going to accept different format strings.
You're gonna see how exactly this works very, very soon.
Anyway, we're going to use Sprintf function, to which you pass the format.
And the format has some placeholders for dates, integers, etc. and then we're just gonna pass some
data that we just know about the error, like we're gonna generate the current date.
So current year month and day and then an hour minute and a second.
That's just an exact format for a date.
Then we're gonna provide the class name of the exception.
You can get that using Getclass function in PHP.
And next up we're going to give the message from the exception.
The file from the exception.
So where the error happened exactly and on which line.
Now it's job of the other methods using this one format error message to come up with the proper format
string.
We're going to get to that very, very soon.
First, maybe we can work on the errors in the CLI.
And this should be a little simpler because for the web errors we also need to produce a view.
So first maybe we can implement this method render CLI error.
Now this method is obviously private.
There is no point in making it public.
It is an internal method.
So it is render CLI error and it accepts variable and the name is the exception.
So its void doesn't return anything.
Now at this point we need to figure out if we are in the debug mode.
So I'd like to use the app container and get the config.
So a quick reminder.
How does it look like we've got this app key and debug key inside.
So we're going to use that.
There is an app key which should have the debug key.
If this happens to be undefined we just provide a default which is false.
Next up if we are in the debug mode we're going to handle it differently than if we are not.
So we need to produce the error message.
And that's the time where we are using the format error message.
Maybe I'm gonna use the static keyword here.
And the first argument there is the exception.
But the second is the format.
Let's produce the format for the CLI.
So in this format parameter we need to just add a placeholders which will be filled with the values
in order.
They are passed to the format error message.
And that's the order.
So we get the date the class message file and line.
So I just enabled the split view so we can see that.
So in the square brackets we might output the time.
And this is done by adding percent s.
This means we want this as a string which would relate to that date.
And then we can say we've got an error.
Then percent s would be the class name.
We can have another colon and the percent s would be the message.
Then we can say in another S string placeholder that would be the file online percent d as that's an
integer.
So we have a number.
So D stands for decimal.
At the end we can add a line break.
And that would be the basic error we can display in a terminal.
Now obviously I'd like to spice up things a little bit.
We can close this window already.
And I'd like to add some CLI colors.
Now it's pretty easy to do.
You just need some.
You just need to know some specific symbols.
So what I'm typing right here is the exact symbol that will change the color in the terminal to red.
So you need this slash.
Oh 33 opening square bracket 31.
M so this here is an exact combo that will change the color of all the output to red.
And we don't want really everything to be in red.
So we need to reset that at one point.
And it's up to us where to do that.
Maybe we can do it right after the error.
So to reset we're gonna do again.
Slash.
Oh 33 opening square bracket zero.
M this would just reset the color to the default one, whatever that is.
And that way we would have a really nicely formatted error that is super visible.
But that's not everything.
We can also get a so-called stack trace.
So from the exception we can grab get trace as string.
And what stack Trace is, is basically what were the subsequent method or function calls.
So we can track what was called in what order.
And potentially uh, it's easier to find the flows in the logic of your programs.
We're going to see it obviously.
Now, if we are not in the debug mode, then we might want a simpler error.
So for such cases, we're going to have a simpler error message.
And the trace would be an empty string.
So you don't really want to show your stack trace of your errors.
Uh, if you are not in the debug mode, even on the terminal.
So here the message, I think we can still use the colors.
That's why I'm copying this.
And.
We're going to output the error right here.
And I'm going to remove everything else.
So that's the changing of the color to red.
And this is resetting to the default.
And we're just going to say an unexpected error occurred.
Please check logs or please check error log for details.
And that's it.
Now we can remove those spaces.
I just added them so it's more clear.
But remember that this is just a specific code for changing to red.
And this is a specific code that terminals understand that will reset to the default one.
So we are almost there.
Now we need to output this someplace.
And you do it using f right function.
And we just say that we want to write to the so-called standard error output where we give the error
message.
And if we have the trace we're also going to write it to the standard error output.
Where we can additionally say that maybe after a new line that the stack trace is then another trace
and maybe another new line.
Right.
And then let's make sure we exit with an error code that's non-zero, which would mean that there was
an error.
Okay.
So a lot of stuff was done I think that next up we should try this out.
Let me comment out this line because we don't have this one implemented yet.
Anyway, I think we might try to trigger some error even manually in any of the command line scripts.
But we're going to do this next time, because we also need to register those new error handlers in
our bootstrap file.
So we're going to be testing this next up.