Monolog: how to catch all errors and exceptions - php

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.

Related

set_exception_handler for specific exceptions

I'm using a new API and I want to handle exceptions specific to it, and return the data from the exceptions to JS function that made a request. The thing is - I have a fatal_handler registered with register_shutdown_function in the program, and I want to avoid it for these exceptions, because It won't let me return the necessary data to the JS function, and I don't want to mess with this specific handler because it's more general.
I managed to override it with set_exception_handler, but I assume it will catch other unhandled exceptions as well.
Is there any way to define the instance of the exception (e.g AException) that will be handled in set_exception_handler(), same as in a catch block?
My only idea was to check the type of the exception object I'm getting to the handler function (with instanceof, and rethrow it if it's not the type I'm looking for.

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

php custom exceptions

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.

Unit testing classes - is throwing errors out of the question?

I am getting my head around PHPUnit, and trying to build a test case for an existing class.
The class is a static configuration class, getting, setting and listing configuration options that will be available in the application.
The class is very strictly built. If I try to set a configuration setting with an incompatible value, or a configuration setting that does not exist, a E_USER_ERROR is thrown, halting the execution of the script. Even if it's not the fine art of error handling, it works fine for the purposes of this class. An error in that class is always the result of a programming error, and never of bad user input.
This has the great advantage that you don't have to worry about how error messages are handled or logged, which keeps the code slim. Output the message (or not, in production), die(), done.
However, with Unit tests, I don't see how I can continue to work with classic PHP errors. I will have to convert the functions to return success flags, or throw exceptions.
Am I correct?
Or is there a way in PHPUnit to expect errors, as there is to expect Exceptions? I can't see any straight away.
From the PHPUnit manual:
By default, PHPUnit converts PHP errors, warnings, and notices that are triggered during the execution of a test to an exception. Using these exceptions, you can, for instance, expect a test to trigger a PHP error as shown in Example 4.8.
class ExpectedErrorTest extends PHPUnit_Framework_TestCase
{
/**
* #expectedException PHPUnit_Framework_Error
*/
public function testFailingInclude()
{
include 'not_existing_file.php';
}
}
Same works for exceptions of course.
Edit: didn't see this was already mentioned in the comments, but I'll leave it here for reference in case someone looks for the same question and doesn't read the comments
If you want to cancel treating warning as Exception, use
PHPUnit_Framework_Error_Warning::$enabled=false; .
I don't know the details of your implementation, but couldn't you raise a normal (custom) exception (which can be tested) and have a global exception handler in your app that will throw the proper E_USER_ERROR based on these (custom) exceptions?
Check set_exception_handler for more information on setting this global exception handler.
Couldn't you define an error handler (via set_error_handler) that will treat any error that cannot be handled by PHPUnit (such as E_USER_ERROR) as a failure of the unit test?
(Inspired by WordPress' tests)

Categories