i've got a try catch in the framework i'm using which when the catch is triggered it displays an error report page, one thing in this report page is that it displays a menu where the times came from the database
what i thought it's do is that i'd put another try catch in the catch in case if the database can be connected to, something like this
try
{
code that would throw an excpetion
}
catch(Exception $e)
{
try
{
connect to database
run query
log error in database
output screen using database data
}
catch(Exception $e)
{
output screen using static html
}
}
this way if the exception was a database connection error it will use a static html output rather than the dynamic one generated from database data
however when i cause a database error (deleting a required table) my static html doesn't work
i am wondering if it is even possible for a try catch to work in the catch or weather it's the framework (i'm using magento), i ask this because if it is possible to be done then i'll spend time figuring out why the framework is stopping me
Yes, it is possible to put a try/catch block in a catch block.
However, from your description, it sounds like you want more 'intelligent' exception catching. You can do something like this:
try {
// some operations including something with a database
}
catch (DatabaseException $e) {
// the exception thrown by the code above was a DatabaseException
// output some error message without using the database
}
catch (Exception $e) {
// the exception thrown by the code above could have been any type of exception EXCEPT a DatabaseException
// so you can still try to use the database to compose the error message
}
Note that anything that can throw exceptions can also throw these exceptions when run from a catch block. For example, when the try block throws an exception before it reaches any database code, a database exception can still occur when handling the original, non-database, exception.
Related
I want to set a custom message to be displayed to the user when I throw an error in Laravel 5.1. For example, in a controller I might have:
if(!has_access()){
abort('401', 'please contact support to gain access to this item.');
}
Then my custom error page I would display the error with:
$exception->getMessage();
However, what if there was a SQL error or other event? Wouldn't that also set the Exception Message which I would be unknowingly outputting on my error page?
The PHP docs for getMessage() don't go into much detail about this.
How can I set a specific exception message without introducing any security risk?
However, what if there was a SQL error or other event? Wouldn't that also set the Exception Message which I would be unknowingly outputting on my error page?
Potentially, yes. PHP makes no guarantees that the contents of exception messages will be "safe" to display to users, and it's quite likely that some classes will throw exceptions which include sensitive information in the message.
If you want to use exceptions to display errors to users, use a specific subclass of Exception for those exceptions, and only print the message if the exception was an instance of that subclass, e.g.
class UserVisibleException extends Exception {
// You don't need any code in here, but you could add a custom constructor
// if you wanted to.
}
// Then, in your abort() function...
throw new UserVisibleException($message);
// Then, in your exception handler...
if ($exc instanceof UserVisibleException) {
print $exc->getMessage();
} else {
print "An internal error occurred.";
}
If you access your app.php file:
'debug' => env('APP_DEBUG', false),
In your production env, set this to false. This would make sure that no debug errors would be displayed in the production environment.
Once this is set, you can respond to normal exceptions through your controller. Anything else, laravel wouldn't display the error page.
Yes,
$e->getMessage() can potentially reveal more information about your code IF you use it in a similar way:
try {
$executeSomethingHereForWhichYouExpectAnException();
// Basic \Exception that reports everything
} catch (\Exception $e) {
$error = $e->getMessage();
}
even with 'debug' => false in app.php. For example if you have an error with your code $error would display it - basically ANY type of error (PHP,MYSQL,ETC);
However, there is a fix - to catch your CustomException messages and prevent typical error displaying if you use it in like so:
try {
$executeSomethingHereForWhichYouExpectAnException();
// Our custom exception that throws only the messages we want
} catch (\CustomException $e) {
// Would contain only 'my_custom_message_here'
$error = $e->getMessage();
}
What is the difference you may ask - the difference is that instead of \Exception which is the basic error reporting, we use \CustomException class, which you throw from $executeSomethingHereForWhichYouExpectAnException() function:
executeSomethingHereForWhichYouExpectAnException(){
if (something) {
throw new CustomException("my_custom_message_here", 1);
}
}
If you have more exceptions you can include them like so (as of PHP7.1):
try {
something();
} catch(\CustomException | \SecondCustomException $e) {
// custom exceptions
} catch(\Exception $e) {
// basic exception containing everything
}
This probably sounds ridiculous. However, if you don't ask you'll never learn.
I'm relatively new to PHP and self-taught so I haven't exactly learnt everything "to the book".
Is the following required:
try {
}
catch {
}
Am I right in thinking that the try will try to "execute" the code within the brackets and the catch will try and catch the result of the outcome? If there is nothing to catch then it will throw an error?
The first assumption is correct: the code in try will be attempted to run.
However, if no error is thrown, then the block exits normally. If there is an error thrown, then the try execution ends early and goes into the catch block. So your second idea is switched.
try catch is used for exception handling or error handling.Put your script in try block and write your custom error message in catch block.
try{
// put here script
}catch(Exception $error){
//your custom message
echo 'Caught exception: ', $error->getMessage(), "\n";
}
If your script does not execute then it will be jump catch block and access message using $error object.
What is the benefit? The benefit is the whole script will not be stop to execute. It will be continue other block.
In the try block you execute code, whenever something fails in that block it will jump to the catch block. You usually define a variable holding the exception.
So to answer your question, no it will not process the catch block when there is nothing going wrong in the try block. (unless you specifically throw an exception)
try {
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Try block is hold the code which you want to execute. and Catch block is hold the code if you have cause any error then it will execute the catch code or error message.
Basically try and catch we are using for the error handling and avoid to break the control flow of the program and page.
Simple example:
<?php
class A {
public function getA($a = 0)
{
if ($a === 0) {
throw new ItCantBeZeroException("Message");
}
return $a;
}
}
// I want to throw default exception because I'm not sure
// am I doing it right or what can I do with bad parameter.
$a = new A;
echo $a->getA(0);
// Now, I know what I can do if developer write bad input.
// It can't be 0, so I just print my custom error message
// to my page.
try {
$a = new A;
echo $a->getA(0);
} catch (ItCantBeZeroException $e) {
echo "Parameter can't be zero. Try again.";
}
?>
You can define your own exceptions (like ItCantBeZeroException). Exceptions throw error on site (like "Message") but we can catch them and change to something we want.
You write simple class where some code must be string or integer between 0 and 20.
You use this code, but when user make variable 21, simple class throw error.
You refactor code to catch exception and try to fix code, e.g. change any integer greater than 20 to 20. Then code works properly.
Try and Catch is known as Exception Handling
According to w3schools:
Exceptions Handling are used to change the normal flow of a script if a specified error occurs.
For More:
http://www.w3schools.com/php/php_exception.asp
I am having an issue where an exception is being thrown but not caught in Module.php. The code that throws the exception is wrapped in a try/catch. There's nothing really fancy going on so I am assuming ZF2 has a quirk and/or reason for not allowing exceptions to be caught here.
The code is as follows (simplified as necessary):
class Module
{
public function onBootstrap(MvcEvent $e)
{
// Get service manager, etc.
// Set up some environment stuff
try {
// exception is thrown
}
catch (\Exception $e) {
echo $e->get_message();
exit;
}
}
}
Why is the exception not being caught?
In an ideal world there would be a way to catch this exception here. But if that is not possible, or is too convoluted to be worth the effort, an alternative process to fetching this data (regardless of source) as early in the page loading process as possible would be appreciated.
meta
I know the code in Module.php is supposed to be lightweight. But we have to fetch some data immediately before any action is performed as it will contain data vital to those actions to be performed. This data is cached after the first visit so every other page load will avoid this overhead.
I also have Googled this but apparently no one else has either experienced this, asked about it, or documented it.
This code works just fine for me in a module class:
public function onBootstrap(MvcEvent $e)
{
try {
// exception is thrown
throw new \Exception('My exception here');
}
catch (\Exception $e) {
echo $e->getMessage();
exit;
}
}
It displays the exception message and exits.
One way to investigate what is happening is to use xdebug for step by step debugging.
Just add a breakpoint in your Module and see what ZF is doing.
Ok, I understand the "accepted answer" that was given for this question, but it's still not clear to me what kind of code should I put in finally blocks.
If the use of finally is to get the non-catched exceptions thrown and give a general error message for the system not explode for the user, wouldn't appear two error messages for the user if some exception was catched?
[Edit]
Like #MarkBaker said, the "finally" isn't for catch the uncaught exceptions, the generic catch(Exception $e) do that. So... for what it's useful? Or, in other words, what the finally block does that I can't do after the try/catch blocks without finally?
Maybe the following explanation will better help you understand how it works:
try {
function1();//this might throw an exception
function2();//if we want function2 to be executed regardless
//if an exception was thrown from function1() - this
//is not a good place to call it!
} catch (Exception $e) {
echo $e->getMessage();
} finally {
function2();//then the right place to write it will be in a finally clause.
}
When an exception is thrown from function1() - function2() will not be executed - the execution will "jump" to the catch section. If we want function2() to be executed regardless if an error was thrown, for example, if function1() opens a connection to the DB and runs some selects and function2() closes that connection, then we'd better place the call to function2() in the finally block that follows the catch
The 'finally' block should hold code you want executed regardless of the outcome of the try/catch block. For example, if you try to query a database and catch the error, you would still likely want to close the database connection, regardless of whether the database operation succeeded or not. See below:
open_database_conn();
try{
query_database();
return_result();
}
catch(Exception $e){
echo $e->getMessage();
}
finally{
close_database_conn();
}
I'm using an external file with $errmsg array for displaying errors, like:
'app_init' => 'Cannot initialize application',
Using conditionals, I call the function to display the message on failure:
if(!$condition)
{
$arraywithmessages->functionforfiltering($err,'app_init',$aim);
}
...where $err is the array of messages, and $aim is predefined method of publishing error (e-mail, view, etc...)
Now I'd like to make use of Exception Handling, but I don't know where to start. Can anyone help? This doesn't seem to work:
try {
if (!$condition) {
throw new Exception('app_init');
}
// continue
} catch (Exception $e) {
$arraywithmessages->functionforfiltering($err,$e->getMessage(),$aim);
}
I don't know exactly what you want to achive but you should remember that try, catch should be used wisely. It should be used for Exceptional situations only. If you don't use them in that way then it's GOTO code.
About exceptions, remmeber that you can extend Exception class and make your own exceptions and catch them in multiple catch blocks, there is also finally block.
About the constructor of Exception. It has the second param which is $code you can use it to show proper message.
$err = array(0x1 => 'my error app init');
try {
if (!$condition) {
throw new Exception('app_init', 0x1);
}
// continue
} catch (Exception $e) {
echo $err[$e->getCode()]; //it shouldn't be only echo it should do some tries to fix the code close streams etc. not just echo.
}
There is also function
set_exception_handler(). which:
Sets the default exception handler if an exception is not caught within a try/catch block. Execution will stop after the exception_handler is called.
Consider using it. There are a lot of things that can be found in manual.