php custom exceptions - php

I was wondering how would one go about writing custom exception handlers.
so that I can do something like
throw new dbException($sql, $message);
and have it output
There was an error in your query
Message: {$message here}
Query: {$sql here}
Line: {line exception was thrown on}
File: {file exception was thrown from}
but I also want to to catch eg syntax errors and parse errors (if possible)

Well, you can extend the Exception class however you like. For custom exceptions, you might want to check out the post:
PHP 5 OOP: Delegation and Custom Exceptions
You should also find this thread useful:
Custom Exception Messages: Best practices

Unless I am misunderstanding your question, you should be able to extend PHP's Exception class.

Why don't use just write your own exception class derived from the standard base exception? See extending exceptions manual.

Related

The proper way to do exception handling

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?
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.

Monolog: how to catch all errors and exceptions

I'm missing something really obvious.
How can I make monolog record all php errors, php user errors, and exceptions?
Before using monolog, I wrote my own functions which I passed to set_error_handler(), register_shutdown_function() and set_exception_handler(). Is there a way of doing this using Monolog's API, or do I have to the following?
Write an error handler and exception handler which I pass to PHP's functions above
In those handlers, call the appropriate Monolog functions such as Logger::addError(...) using a switch statement or similar
Surely there must be a Monolog API that does the above in a single call?
From the ErrorHandler class docs:
use Monolog\ErrorHandler;
$logger = new Logger('Logger Name');
ErrorHandler::register($logger);
Old question but since it was not yet answered - ErrorHandler will do exactly what you're after.
From The documentation:
ErrorHandler: The Monolog\ErrorHandler class allows you to easily register a Logger instance as an exception handler, error handler or fatal error handler.

Log all exceptions thrown in PHP

I would like to log the stacktrace of all exceptions thrown caught or uncaught.
Is there a way to do this without having to change every catch method in my application?
Thanks!
You can use set global exception handler so you will get all uncaught exceptions.
You can use the methods from the phps base Exception class.
Use getMessage to get the message Oh no! and use getTraceAsString to get a formatted trace.
refer : Log caught exception with stack trace
You could use https://github.com/php-test-helpers/php-test-helpers to override base exceptions __construct. Just add the 'logging' logic. There is a reason why this package is called test-helpers . I don't recommend using it on production.
Anyway...it is better to rewrite your app :)

Storing a PHP exception object in a database

I have need to store a PHP Exception object in a mysql column. It's for an offline error logging system. Usually I would just serialize() the Exception object and be done with it, but half the time, when trying to do that, I get the following error:
Fatal error: Uncaught exception 'Exception' with message
'Serialization of 'Closure' is not allowed'
I am not sure how to get this to work consistently. I will greatly appreciate anyone who has an answer to this problem.
Thanks.
The exception object to be logged contains an instance of Closure class, PHP's implementation of anonymous functions and closure. Apparently anonymous functions cannot be serialized.
You need to investigate your exception classes and see if any of them is supposed to contain them. Normally, exception classes shouldn't have an anonymous function as property.
This reproduces the same error message as your case:
$exception = new Exception('BOO');
$anonymousFunction = function() { echo 'blah'; };
$exception->anonymousFunction = $anonymousFunction;
serialize($exception);
So dig in through your code, your framework's code, your library's code, and try to find out which exception class did have an anonymous function as class property, who assigned them, why - and then you should be able to create a special case for it.
Hope this helps.
http://php.net/manual/en/function.set-error-handler.php
here's the global error handler definition function. you can define a global error handler and make it write the error description to the database.
And the structure of the exception class :
http://php.net/manual/en/class.exception.php

Has trigger_error() in PHP been deprecated for something better in PHP5?

I used to use this when I wanted to trigger errors in PHP, coming from a PHP4 background. Note I had my own set_error_handler() for handling these errors.
if ($error) {
trigger_error('Sorry, error has occured');
}
I can't remember where, but sometime ago someone told me I should be 'using exceptions'. As I'm re factoring a lot of my old code, I figured now is the time to get some good advice on my error handling implementation.
Now that I'm using PHP5 (and a bit smarter than I was when I wrote the older code), is my trigger_error() just an old way of doing things, and if so, what is the best way to handle errors in PHP5?
Yes, you may want to start looking into the PHP 5 exception model. Remember though that just because something is new doesn't mean that you must adopt it. Only adopt those features that you need and make sense in your domain.
That being said, I feel that exceptions are a good concept to grasp and even if you decide not to adopt them you will be all the better for the experience.
I would like to suggest that you read PHP: Exceptions - Manual:
PHP 5 has an exception model similar
to that of other programming
languages. An exception can be thrown,
and caught ("catched") within PHP.
Code may be surrounded in a try block,
to facilitate the catching of
potential exceptions. Each try must
have at least one corresponding catch
block. Multiple catch blocks can be
used to catch different classes of
exeptions. Normal execution (when no
exception is thrown within the try
block, or when a catch matching the
thrown exception's class is not
present) will continue after that last
catch block defined in sequence.
Exceptions can be thrown (or
re-thrown) within a catch block.
I would also encourage you to read What Is an Exception? (Note this is a Java tutorial but the concepts are universal)
When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.
Edit: In order to implement a global exception handler (basically in order to establish a default exception handler that will handle previously unhandled exceptions) you will want to us the set_exception_handler function.
Using exceptions is the object-oriented way to trigger and handle your own application errors.
The PHP manual topic on exceptions is probably a good place to start.
Here is a small example:
function doSomething() {
if ($error) {
throw new Exception('Some descriptive error message.');
}
}
try {
doSomething();
}
catch (Exception $e) {
die('<p class="error">' . $e->getMessage() . '</p>');
}

Categories