The proper way to do exception handling

2019-09-15 01:57发布

问题:

Now what I generally do when writing code is something like this

function changeBookAuthor(int $id, string $newName){
  if(!$newName){
   throw new MyAppException('No author name was provided');
  }

  $book = Books::find($id);

  if(!$book){
   throw new MyAppException('The provided book id could not be found');
  }
}

in the laravel doc we see:

https://laravel.com/docs/5.4/errors

public function report(Exception $exception)
{
    if ($exception instanceof CustomException) {
        //
    }

    return parent::report($exception);
}

Now how to I properly handle the exception? they are all the same exception and they have no code neither. Should I provide an error code?

the problem with php exception is that they use integers. Is quite annoying imho. Better would be 'changeauthor_bookid_notfound' as code instead of a random number. Should I create an exception class for each single exception? e.g. not reuse MyAppException that seems a bit tedious. I would have a trillion classes.

Now if for a special exception I want special handling, with my code, I cannot easily do it. I have no code to check for (e.g. $exception->code == 3331 then do special) and I don't have custom exception classes neither

what is a proven good solid way to handle this case? code, new class on each error, something else all together?

and if provide a code, what is a nice way to do it?

回答1:

The "proper" way to do it would be to define either a custom Exception class for each exception, or to define custom exceptions based on the type of error being thrown, however realize that Laravel already has many built in exceptions and mechanics for handling the use cases you outlined.

For instance, in the case of the "Book Not Found" exception, rather than manually triggering an exception yourself, you could use Books::findOrFail($id); which throws an instance of ModelNotFoundException when appropriate.

Also, in PHP there is no need to handle exceptions for unprovided arguments. Unless expressly denoted as optional, all method arguments are required, and Laravel will throw a PHP exception if an argument is missing.

Additionally, Laravel provides the abort() magic method which throws a HTTP error along with a custom error message and can be used like so:

abort(418, "I'm a teapot...")

So, if you must reinvent the wheel, the proper way is to define custom exception classes and define the custom handlers for those classes, but realize that Laravel already has many built in tools for managing exceptions without needing to do so.