As far as I know, the exception handler should handle any exceptions in any part of my script (classes, functions, etc.).
My exception handler doesn't catch any exceptions although, I tried many times and versions. Can someone help me find the problem? I use nginx & php-fpm (latest).
<?php
require_once 'vendor/autoload.php';
set_exception_handler(['\App\Core\ExceptionHandler','handler']);
The exception handler -
namespace App\Core;
class ExceptionHandler
{
public static function handler(\Throwable $e)
{
.....
}
}
I managed to solve the problem by using proxy class.
So, all of my calls to the controllers wrapped by a main controller class with try-catch block.
So, when our script throws exception, we can send it to our exception handler.
I think it's a better solution after all.
Related
I just recently ugraded to php7 and had my first problem when upgrading some applications using try catch
PHP7 now implements its own error class to handle the errors so the old code that i had:
try {
dispatcher::run(new request);
} catch (Exception $e) {
require_once APP_PATH . 'error.php';
$error = new error($e);
}
now throws an error because error class is already defined:
Cannot declare class error, because the name is already in use in [...]
Now this got solved pretty easily just renaming my error class, but it had me wonder, is there a way to extend the error class of 7, and can be both compatible with php5?
Regards...
The short is you shouldn't do that, because it's a backwards incompatible change.
The long answer is yes, it's possible, but you still shouldn't do that, because it can still result in undesired behavior and still might require making changes to your existing PHP 5 implementation.
The Error class in PHP 7 implements the same Throwable interface that Exception implements. The idea was to just have a distinguishing way to identify those exceptions thrown by PHP itself and those thrown by your PHP code. So what you're doing here $error = new error($e) is basically the equivalent of $error = new Exception($e), which would be backwards compatible with PHP 5, assuming your custom Error class is compatible with the Throwable interface. Since you didn't provide your class implementation I can't say for sure, but generally speaking, if you hadn't already extended Exception in PHP 5, I somehow doubt it will be.
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.
I have some code that makes db calls and network requests and I have it wrapped in a try/catch. The problem is that I can never catch the exceptions, and they don't appear to be fatal exceptions:
try {
// make db requests and network calls
} catch (Exception $e) {
// handle exception
}
Namely, I encounter exceptions such as these:
[Illuminate\Database\QueryException]
[PDOException]
[InvalidArgumentException]
Is there a way to catch these exceptions? Do I need to be explicit for each possible type of exception object (meaning I must create many try/catches), or is there a recommended way of catching non fatal exceptions?
Make sure you're using your namespaces properly, by including the Exception class at the top of your controller like this:
Use Exception;
If you use a class without providing its namespace, PHP looks for the class in the current namespace. Exception class exists in global namespace, so if you do that try/catch in some namespaced code, e.g. your controller or model, you'll need to do:
try {
//code causing exception to be thrown
} catch(Exception $e) {
//exception handling
}
If you do it like this there is no way to miss any exceptions.
Otherwise if you get an exception in a controller code that is stored in App\Http\Controllers, your catch will wait for App\Http\Controllers\Exception object to be thrown.
Recently I have been developing in Zend Framework. I came into a confusion during exception handling.
Can anybody let me know where is the best place to handle exception? Whether it is model or controller? It may be in terms of performance or usability or anything else.
If we want to catch all kinds of exceptions, we better enable our model to throws exception. You can read this post also link
You should handle exceptions in your controllers because sometimes the error messages of exceptions should be passed on to views. To avoid the dependency between models and views you should handle exceptions in your controllers.
Zend Framework all ready handles exceptions through the inbuilt errorController. You can enable it by placing the following line in your config file.
resources.frontController.throwExceptions = 0
Also, if you want to handle exceptions your self, rather then handling them at different places you can just handle them at one place. Something like below.
Tell Zend Framework to not handle exceptions. Do this in your application.ini
resources.frontController.throwExceptions = 1
Do following in your Bootstrap class.
Define a custom method to handle exceptions.
public function __handleExceptions(Exception $e){
//render a view with a simple error message for the user
//and send an email with the error to admin
}
Override the _bootstrap() and run() methods of Zend_Application_Bootstrap_Bootstrap in your Bootstrap class and catch the exceptions thrown during the bootstrap process or while running the application and call your exception handler as shown below.
protected function _bootstrap($resource = null)
{
try {
parent::_bootstrap($resource);
} catch(Exception $e) {
$this->__handleExecptions($e);
}
}
public function run()
{
try {
parent::run();
} catch(Exception $e) {
$this->__handleExecptions($e);
}
}
Now all your exceptions will be handled from a single place.
I've used exceptions in Java and like the way it won't let you call a method unless you catch or throw the exceptions that it might throw.
I'm looking for something similar in PHP. I realise PHP is more dynamic than Java, and doesn't even let you define the exceptions that it throws, but what is the closest I can get?
We document our methods using PHP Doc, so something that triggered an E_WARNING if you called a method without the correct try/catch block, or threw an exception without the correct #thows comment, would be perfect.
There's no way to do it in PHP itself. You will have to parse PHP and figure it out yourself. Try writing phc plugin for this.
I don't think you can reasonably get very close at all, because the language core provides just nothing whatsoever for you to work with. At best, you'd wind up creating some kind of entirely user-space funcall/exception validation mechanism that would have an absolutely horrific impact on performance.
I'm not sure that you can accomplish your stated goal. The PHP environment doesn't analyze what a function might or might not do, which would generally be a compile-time operation for other languages (I would think). I don't think you can even find that sort of thing via Reflection.
You are wrong however when you say that you can't define the exceptions that get thrown, as the Exception base class is fully extendable. PHP doesn't throw any exceptions by default though, it triggers errors. There is a fundamental difference between triggered errors and Exceptions, the latter being a user-land construct for the most part.
This isn't your question, but I'd put out a suggestion that if you wanted to move to a fully Exception-oriented environment, you could write your own error handler using set_error_handler() and manage the PHP triggered errors, and have it throw out an Exception.
I think you can simply reproduce this behavior in PHP using exception handlers and reflection.
class YourException extends Exception {
public function __toString() {
return __CLASS__;
}
}
class MyObject {
public function __construct(){}
/**
* #throws MyException
*/
public function myMethod() {
return 'foo';
}
}
try {
$o = new MyObject();
$o->myMethod();
}
catch(YourException $e) {
$method = new ReflectionMethod('MyObject', 'myMethod');
$method->getDocComment();
$throws = // Get the #throws comment (foreach, regexp, whatever);
if($e === $throws) {
// do something
}
}
Setting your own exception handler.
Grab and analyse the comments with Reflection mechanism (see getDocComment)