So i'm trying to learn about exceptions. And i've come accross something people often do , but dont really explain why they do it and how it works. Maybe this is something that speaks for itself but I still dont get it, I apologize if this question might come over as a bad question.
Basically this is the code I'm working with:
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
What is $e where is this variable defined. I have an idea.
What i'm thinking is that you're assigning the exception object to the variable $e but i'm not sure. Shouldnt it be catch (Exception = $e) ?
It works pretty much the same as function parameters:
function foo(Bar $bar) { ... }
You use a type hint Bar followed by the parameter name $bar, and that declares the variable.
In the case of try..catch, that declaration happens in catch:
catch (Exception $e) { ... }
This uses the type hint Exception, which here is used to specify which kinds of exceptions the catch is supposed to catch. You can limit the catch to specific kinds of exceptions and/or define multiple different catch blocks for different kinds of exceptions. The exception itself is then available in the variable $e. You can use any arbitrary variable name here, just as for function parameters.
Uhm, now that i think about it, i have always considered the Exception $e to be the input for the catch() call.
As far as i know, you are not defining $e, as it is already thrown, you are just passing it to the catch() block, as you would do with a function name($input){}
In this code
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
The keyword Exception is the type for the parameter $e.
In PHP Exception is the base exception class that all exceptions derive from so that catch block is a catch-all for all exceptions.
i.e. You might want multiple handlers for different exception types before the catch-all:
try {
someOperation($parameter);
} catch(DatabaseException $e) {
echo 'Database Exception: ' .$e->getMessage();
} catch(Exception $e) {
echo 'General Exception: ' .$e->getMessage();
}
Related
I have a problem where I want to catch all exception except descendants of my custom exception.
Maybe bad design, but here it is (Simplified and names changed, but the code is quite accurate):
function doStuff()
{
try {
// code
if (something) {
// manually throw an exception
throw StuffError("Something is bad.");
}
// a third-party code, can throw exceptions
LibraryClass::arcaneMagic();
} catch (Exception $e) {
throw new StuffError("Error occured while doing stuff: "
. $e->getMessage());
}
}
/** My custom exception */
class StuffError extends Exception
{
function __construct($msg) {
parent::__construct('StuffError: ' . $msg);
}
}
However, the issue here is that I don't want the try-catch to intercept the manually throws StuffError. Or, seamlessly rethrow it or something.
As it is now, I'd get:
StuffError: Error occured while doing stuff: StuffError: Something is bad.
I want just:
StuffError: Something is bad.
How would I do it?
You can have multiple catch clauses, and the first one that matches will be the one that runs. So you could have something like this:
try {
do_some_stuff();
}
catch (StuffError $e) {
throw $e;
}
catch (Exception $e) {
throw new StuffError(Error occurred while doing stuff: " . $e->getMessage());
}
But you might want to rethink wrapping stuff like this. It obscures the real cause of the error. For one thing, you lose the stack trace. But it also complicates error handling, since now someone can't differentiate exception types the way you're trying to do, short of trying to parse the exception message (which is rather an anti-pattern in itself).
I might be misinterpreting you, but I think this is what you're looking for:
...
} catch (Exception $e) {
if (get_class($e) == 'StuffError' || is_subclass_of($e, 'StuffError')) {
throw $e;
} else {
throw new StuffError("Error occured while doing stuff: "
. $e->getMessage());
}
}
...
Replace your catch statement with the code above. It checks to see if the exception is a StuffError or a child class of StuffError. I'm still very confused at why you would need to throw a StuffError exception after you catch, but maybe that's just some weirdness coming from translating/cleaning your code.
A very simple question from someone without much experience. The following try catch block has the section, "(Exception $e)" : is this like sql, where $e becomes an alias of Exception? If so, is this type of alias assignment used elsewhere in php, because I haven't come across it? I have searched for hours without being able to find an explanation on the web.
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "<br/>";
echo inverse(0) . "<br/>";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "<br/>";
}
echo 'Hello World';
What you mention is a filter construction. It resembles a declaration as known from other, declarative languages. However it has a different meaning in fact. Actually php does not have the concept of an explicit declaration (which is a shame...).
Take a look at this example:
function my_func($x) {
try {
/* do something */
if (1===$x)
throw new SpecialException('x is 1.');
else if (is_numeric($x)) }
throw new SpecialException('x is numeric.');
else return $x;
}
catch (SpecialException $e) {
echo "This is a special exception!";
/* do something with object $e of type SpecialException */
}
catch (Exception $e) {
echo "This is a normal exception!";
/* do something with object $e of type SpecialException */
}
}
Here it becomes clear what the construction is for: it filters out by type of exception. So the question which of several catch blocks is executed can be deligated to the type of exception having been thrown. This allows a very fine granulated exception handling, where required. Without such feature only one catch block would be legal and you'd have to implement conditional tests for potential exception types in each catch block. This feature makes the code much more readable, although it is some kind of break in the php syntax.
You don't have to, but you can create own exception classes with special behavior and, more important, accepting and carrying more information about what actually happened.
It's OO PHP. The $e is an instance of the exception object.
$e could easily be labelled anything else, so long as it's referred to thereon when you want to getmessages, etc.
For instance;
try {
echo inverse(5) . "<br/>";
echo inverse(0) . "<br/>";
} catch (Exception $oops) {
echo 'Caught exception: ', $oops->getMessage(), "<br/>";
}
In the controllers class files, most of the method functions include try/catch block something like this:
try
{
$stmt = $this->prepare($sql);
$stmt->execute($params);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
//foreach() or so on...
}
catch (Exception $e)
{
//bunch of code...
//save error into database, etc.
//error into json and pass to view file
}
There are a lot of code in the catch block, is there a way to reduce it. Is possible to add "throw exception" in the catch block?
Yes, it is. Try it by yourself. You can always throw a new Exception in a catch block or rethrow the same exception.
try
{
// ...
}
catch (Exception $e)
{
// do whatever you want
throw new Your_Exception($e->getMessage());
// or
throw $e;
}
I don't know what "bunch of code" is. I'm not sure I believe you. If you have that much going on in a catch block you're doing something wrong.
I'd put this kind of code into an aspect if you have AOP available to you.
"Error into database" might throw its own exception. What happens to that?
The only step that I see here that's necessary is routing to the error view.
What does rethrowing the exception do? It's just passing the buck somewhere else. If all these steps don't need to be done, and all you're doing to rethrowing, then don't catch it at all. Let the exception bubble up to where it's truly handled.
You shouldn't be catching Exception. That's much too general. Catch each specific type of Exception with multiple catch statements on your try block:
try {
} catch(PDOException $err) {
} catch(DomainException $err) {
}
I am a strong Python programmer, but not quite there when it comes to PHP. I need to try something, and if that doesn't work out, do something else.
This is what it would look like in Python:
try:
print "stuf"
except:
print "something else"
What would this be in PHP?
http://php.net/manual/en/language.exceptions.php
try {
print 'stuff';
} catch (Exception $e) {
var_dump($e);
}
Note: this only works for exceptions, not errors.
See http://www.php.net/manual/en/function.set-error-handler.php for that.
try {
// do stuff ...
} catch (Exception $e) {
print($e->getMessage());
}
See http://php.net/manual/en/language.exceptions.php
PHP does not natively support error catching like Python does, unless you override the default behavior and set your own error handler. PHP's try - catch was only recently added to the language in version 5, and it can only catch exceptions you explicitly throw.
So basically, PHP distinguishes between errors and exceptions. Errors haven't been modularized and made available to the user like they have been in Python. I believe that's related to the fact that PHP began as a collection of dynamic web scripts, grew and gained more features over time, and only more recently offered improved OOP support (i.e., version 5); whereas Python fundamentally supports OOP and other meta-functionality. And exception handling from the beginning.
Here's an example usage (again, a throw is necessary, or else nothing will be caught):
function oops($a)
{
if (!$a) {
throw new Exception('empty variable');
}
return "oops, $a";
}
try {
print oops($b);
} catch (Exception $e) {
print "Error occurred: " . $e->getMessage();
}
You can handle PHP errors like they were exceptions by using set_error_handler
In this error handler function you can throw various exception, according to error level for instance.
By doing this you can treat any error (including programming errors) in a common way.
PHP 5 has the exception model:
try {
print 'stuff';
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Assuming you're trying to catch exceptions, take a look at http://php.net/manual/en/language.exceptions.php
You could try something like
try {
echo "Stuff";
} catch (Exception $e) {
echo "Something Else";
}
I been searching for this and I just seem to run into the same articles, in this code:
try
{
//some code
}
catch(Exception $e){
throw $e;
}
Where does $e gets stored or how the webmaster see it? Should I look for a special function?
An Exception object (in this case, $e) thrown from inside a catch{} block will be caught by the next highest try{} catch{} block.
Here's a silly example:
try {
try {
throw new Exception("This is thrown from the inner exception handler.");
}catch(Exception $e) {
throw $e;
}
}catch(Exception $e) {
die("I'm the outer exception handler (" . $e->getMessage() . ")<br />");
}
The output of the above is
I'm the outer exception handler (This is thrown from the inner exception handler.)
One nice thing is that Exception implements __toString() and outputs a call stack trace.
So sometimes in low-level Exceptions that I know I'm gonna want to see how I got to, in the catch() I simply do
error_log($e);
$e is an instance of Exception or any other class that extended from Exception. Those objects have some specific attributes and methods in common (inherited from the Exception class) you can use. See the chapter about exceptions and the Exception member list for more details.
I'm assuming your using some sort of third party code/library with this code in it that is throwing the exception into your code. You simply have to be ready for an exception to be thrown to catch it, then you can log it/display it however you want.
try {
$Library->procedure();
catch(Exception $e) {
echo $e->getMessage(); //would echo the exception message.
}
For more information read the PHP manual's entry on Exceptions.
The lines:
catch(Exception $e){
throw $e;
}
Don\t make sense. When you catch an Exception you're suppose to do something with the exception like:
catch(Exception $e){
error_log($e->getMessage());
die('An error has occurred');
}
But in your case the Exception is thrown directly to an outer try-block which would already happen.
If you change your code to:
//some code
Would create the exact same behaviour.