Before I get into the question, I'll give you a brief introduction into what I want to do. I want to be able to show a friend;y view to users when a error happens in my Laravel project but unfortunately I don't know how to do this and was hoping some of you may be able to help me?
Hello. Today I am asking a question about Laravel. For a long time I have wanted to log EVERY single error in my laravel project. Now some of you may say that its easy, just overwrite the handle() method in the App\Exceptions\Handler class.
While that's relatively easy to do, it doesn't handle EVERY single error. I have noticed it doesn't handle Query exceptions.
What I am asking is how can I handle EVERY exception. What I mainly want to do is log the error in a database table, and disable a nice view to the end user. Then if I am the one, or another member of my team that receives the error, they can easily check in the database without having to show any critical details to the end user.
I followed this tutorial but it's the same, it doesn't log every single exception.
http://blog.sarav.co/registering-custom-exception-handler-laravel-5/
You can simply add some code in the App\Exceptions\Handler::render method, for example:
public function render($request, Exception $exception)
{
if($exception instanceof \Illuminate\Database\QueryException) {
// Do something with the $exception
// dd($exception); // analyze it
// return a response/redirect
}
return parent::render($request, $exception);
}
In this $exception instance, you can find many useful information using following methods (Omit magic methods, it's a dump of get_class_methods):
array:12 [▼
0 => "__construct"
1 => "getSql"
2 => "getBindings"
3 => "__wakeup"
4 => "getMessage"
5 => "getCode"
6 => "getFile"
7 => "getLine"
8 => "getTrace"
9 => "getPrevious"
10 => "getTraceAsString"
11 => "__toString"
]
Also, the property $exception->errorInfo will give you some information as well, for example (One particular errorInfo):
errorInfo: array:3 [▼
0 => "42S22"
1 => 1054
2 => "Unknown column 'ids' in 'field list'"
]
Note: FYI, error and exception are two different things so the set_error_handler and the set_exception_handler both are for different reasons, an error handler will not catch an exception.
Use set_error_handler to set custom exception. Or you could use log4php they have a package for laravel I believe.
Related
I need to test if my application logs written with correct data (I know in most cases it's not very important to check logs, but it's very important in this specific case).
So log looks like this:
$this->logger->error(
'Invalid survey provided',
[
'exception' => $e,
'survey' => $survey
]
);
and in the spec I have a code:
$exception = new ValidationException(
sprintf(
'Provided survey "%s" does not have all required fields %s',
json_encode($surveysResponse['result'][0]),
json_encode(Survey::$requiredFields)
)
);
$logger->error(
'Invalid survey provided',
[
'exception' => $exception,
'survey' => $surveysResponse['result'][0]
]
)->shouldBeCalled();
and spec failing b-z mock not matching, but I'm sure that same error message with same survey and exception with same error message actually logged. I'm not able to tell you exact issue as error output is huge and trimmed. But I'm 90% sure it's failing while comparing exception object because exceptions are not exact the same objects.
This might be the wrong approach, because the log entry will not be the same due to different timestamps on the log entry. Just preg_match() the log file, spanning multiple lines, obviously with a wildcarded timestamp. Then it should be save to assume that they're "the same", when the count of returned matches equals two (assuming a truncated log file, to begin with). Check out \PHPSpec\Matcher .beTrue() in combination with said condition.
I am trying to sort out error and exception handlers. With a fatal error, I send myself a text message, and with other errors I get an email. (I added the arrays at the end in case they may be useful.)
For errors there is https://php.net/manual/en/errorfunc.constants.php I but cannot find anything similar for exceptions.
I believe I can set my own exception values but are there agreed severity levels for general exceptions, PDOExceptions etc. The only place I find severity mentioned is in ErrorException. (I only use PDOExceptions at the moment but am trying to catch other "general" ones.)
Is a severity helper chart available somewhere? I freely admit I am struggling with exceptions.
PS I had a look at https://www.php.net/manual/en/errorexception.getseverity.php but that looks like it is for errors being sent as exceptions. I am quite confused now.
Error code arrays in case they are useful.
$phpErrorCodes = array (
1 => "E_ERROR",
2 => "E_WARNING",
4 => "E_PARSE",
8 => "E_NOTICE",
16 => "E_CORE_ERROR",
32 => "E_CORE_WARNING",
64 => "E_COMPILE_ERROR",
128 => "E_COMPILE_WARNING",
256 => "E_USER_ERROR",
512 => "E_USER_WARNING",
1024 => "E_USER_NOTICE",
2048 => "E_STRICT E_ALL",
4096 => "E_RECOVERABLE_ERROR",
8192 => "E_DEPRECATED",
16384=> "E_USER_DEPRECATED",
32767=> "E_ALL");
$phpErrorCodesFatal = array (
1 => "E_ERROR",
16 => "E_CORE_ERROR",
64 => "E_COMPILE_ERROR",
4096 => "E_RECOVERABLE_ERROR");
$phpErrorCodesFatalNumberOnly = array (
1 ,
16 ,
64 ,
4096);
//4096 recoverable but dangerous so treated as fatal
Exceptions
Let me try to clarify some misconceptions here.
Are there severity codes for exceptions?
No. All exceptions are severe.
An exception will stop the execution of your script. They are used to prevent the execution of the code which follows if the preceding code could not be executed.
How do I know if they are important?
All exceptions are important. When an exception is triggered it tells you as a developer that something unexpected has happened in the code. The code which you have written simply did not anticipate this happening and to prevent undefined behaviour it should stop processing immediately.
Unhandled exceptions would show up as PHP Warning. - mario
That is not true. Any unhandled exception will be converted to PHP Fatal error. If your application doesn't know how to handle an exceptional situation then PHP must immediately stop! It is not a warning you can ignore or silence; it's a fatal error.
As a rule of thumb I should treat exceptions as fatal errors?
Not necessarily. In rare cases a developer might expect a particular piece of code to throw an exception, which is possible to recover from or work around. The code logic anticipates something going wrong and has a way around the problem. If the exception is caught and handled this will not result in a fatal error.
The difference between an exception and a fatal error is that you can catch and recover from an exception, but not from a fatal error.
So if I don't do anything then exceptions turn to errors.
If you have not caught the exception and you do not have your own error handled implemented then PHP will default to the built-in error handler. The logic is that it will stop the script and throw an error with the exception as a message. This error will then, based on your configuration settings, either be logged on the server or displayed to the user.
Errors
PHP has a bad history. One of the problems with early PHP versions was that it was very lenient when it comes to badly written code. It would either try to guess what the correct action should be or merely warn the user about some serious problem. The outcome of this was that a lot of developers learned to simply ignore the warnings, notices and sometimes even errors.
With PHP 7 few things have changed.
PHP 7 changes how most errors are reported by PHP. Instead of reporting errors through the traditional error reporting mechanism used by PHP 5, most errors are now reported by throwing Error exceptions. An error is still not an exception, but it behaves like one. You can catch the error and if you don't you will still see "Fatal error: Uncaught Error: ...".
Modern PHP functionalities will now use exceptions. This means that userland code should also try to follow the same approach. Throw an exception when your code should stop the execution (don't use die/exit for this) and only catch them when when you know how to recover.
With future PHP releases the notices and warnings might be changed to Error exceptions. Don't ignore them now. Treat all of them as severe problems in your code and fix them now.
As per the comments, the general advice with exceptions is that you should catch them all - in that sense, all unhandled exceptions are severe.
However, you could still classify exceptions in your system in the way that you want. Let's say that at the top level of your app you have a call that enters the main app:
try
{
$this->mainApp();
}
catch (SeriousRuntimeException $e)
{
$this->handleSeriousError($e);
}
catch (TrivialRuntimeException $e)
{
$this->handleTrivialError($e);
}
Then in your code you can throw a SeriousRuntimeException or a TrivialRuntimeException as you see fit. In some cases you will have external exceptions to deal with, and you will need to convert them like so:
try
{
$this->databaseOperation();
}
catch (PDOException $e)
{
// Copy the exception properties that are important to you.
// Throw the appropriate severity based on what handler you
// want to run.
throw new SeriousRuntimeException($e->getMessage());
}
In this example I assume that both exception types are fatal, but they are handled differently. It is conceivable that you could have an exception type that is so trivial that the app keeps running (e.g. in a listener loop - it logs the fault and then carries on).
The problem is that I'm reciving Class 'session' not found error.
But the funny fact is that I'm not using session class. Anyway I'm using session namespace use Session;. I've found out that the problem occurs when I'm returning view.
If I return simple string or number it works, but when I use
return view('catering.prices')->with(['name' => 'Victoria']);
or
return view('greetings', ['name' => 'Victoria']);
I'm reciving the error.
Log:
[2016-10-06 11:38:54] local.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Class 'session' not found' in D:\app\storage\framework\views\397c6d5694d7a10e04cabd271a3359cfd11a387e.php:16
Update
I'm seeing that it's not returning new views - I have now about 40 views. The old one are working well but when I create new views I'm reciving the error.
Answer
The problem was wrongly set permissions for specific user in my database. Thank you for your effort.
Anybody has some idea?
Try like this,
return view('catering.prices',['name'=> 'Victoria']);
OR
return view('catering.prices')->with('name', 'Victoria');
check here : https://laravel.com/docs/5.2/views
I am new to unit testing and now trying to write some test cases using PHPUnit for a Laravel application. I have done one basic test which is like the following :
public function testGetPointsByApp()
{
$this
->json(
'GET',
self::URL.'/'.$value
)
->assertResponseStatus(200)
->seeJson([
'status' => 'success',
])
->seeJsonStructure([
'status',
'message',
'data' => []
]);
}
Now this is working. But I would like to know how can I test for invalid inputs and for the cases like there is not data at all with the given parameters. I am throwing corresponding exceptions in each of these cases and it will add particular messages. How can I test whether it is thrown ?
I don't want to include it to this method and would like to write some other methods to test different scenarios in the API like invalid UUID, no data etc. So for each time, I need to call the API url or this call can be done from any kind of set up function ?
I don't know laravel but in PHPUNIT you can test if exception is thrown with expectException function. For example for InvalidArgumentException
$this->expectException(InvalidArgumentException::class);
You can also use annotation #expectedException and there are also a lot of things that can be tested in exception like expectExceptionCode() etc.
More you can find here
Since you're not doing an Unit test (this kind of test you're doing is an acceptance test), you cannot check for the exception it self, you will look for a bad response:
$this
->json(
'GET',
self::URL.'/'.$BAD_VALUE
)
->assertResponseStatus(422)
->seeJson([
/* Whatever you want to receive at invalid request */
])
->seeJsonStructure([
/* Whatever you want to receive at invalid request */
]);
Laravel validation errors returns 422 - unprocessable entity HTTP code.
You can check the response also for your expected error messages or something else.
I have started to play with the dev version of ZF2 in the current dev-develop branch and since then I am getting white screen on every exception, thrown somewhere in the views.
I have installed the SkeletonApplication to see, if it is something in my application, that was causing it, but same problem appear there too. Downgrading to dev-master solves the problem and I am getting the standard exception dump.
Looking into the zf2 code I think I have found the reason for this. In Zend\Mvc\View\Http\DefaultRenderingStrategy::render() now we have:
public function render(MvcEvent $e)
{
......
try {
$view->render($viewModel);
} catch(\Exception $ex) {
$application = $e->getApplication();
$events = $application->getEventManager();
$e->setError(Application::ERROR_EXCEPTION)
->setParam('exception', $ex);
$events->trigger(MvcEvent::EVENT_RENDER_ERROR, $e);
}
return $response;
}
So the Exception is catched, but the response is empty and I have no clue about the cause of the latter.
However another question appears: How is the error handler going to render the exception page, if the error is triggered in the layout? (Like in my case - the navigation helper, which was unable to find the container.) The only possible solution is to have an extra error layout, but this is pointless, since the reason of having a nice exception handling is not present anymore.
So following questions are arising:
How do ZF2 developers plan to solve the issue?
Is there a current workaround (actually commenting out the try { } catch() { } fixes the problem, but is not a good solution)
Since the pull request, which brought the above code, is closed, am I doing anything entirely wrong and am I completely wrong about the way it should work?
Check your zf2 config files to make sure you have opened exception display options:
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
),