PHP Try-Catch Blocks: Are They Able to Catch Invalid Arg Types

PHP try-catch blocks: are they able to catch invalid arg types?

Warnings and notices are not technically exceptions in PHP. To catch an exception it has to be explicitly thrown, and many of the built-in libraries of functions do not throw exceptions (mostly because they were written before PHP supported exceptions).

It would have been nice if somehow exceptions were built on top of the existing notice/warning/error framework but perhaps that is asking too much.

Catching multiple exception types in one catch block

Update:

As of PHP 7.1, this is available.

The syntax is:

try
{
// Some code...
}
catch(AError | BError $e)
{
// Handle exceptions
}
catch(Exception $e)
{
// Handle the general case
}

Docs: https://www.php.net/manual/en/language.exceptions.php#example-335

RFC: https://wiki.php.net/rfc/multiple-catch

Commit: https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a



For PHP before 7.1:

Despite what these other answers say, you can catch AError and BError in the same block (it is somewhat easier if you are the one defining the exceptions). Even given that there are exceptions you want to "fall through", you should still be able to define a hierarchy to match your needs.

abstract class MyExceptions extends Exception {}

abstract class LetterError extends MyExceptions {}

class AError extends LetterError {}

class BError extends LetterError {}

Then:

catch(LetterError $e){
//voodoo
}

As you can see here and here, even the SPL default exceptions have a hierarchy you can leverage. Additionally, as stated in the PHP Manual:

When an exception is thrown, code following the statement will not be
executed, and PHP will attempt to find the first matching catch block.

This means you could also have

class CError extends LetterError {}

which you need to handle differently than AError or BError, so your catch statement would look like this:

catch(CError $e){
//voodoo
}
catch(LetterError $e){
//voodoo
}

If you had the case where there were twenty or more exceptions that legitimately belonged under the same superclass, and you needed to handle five (or whatever large-ish group) of them one way and the rest the other, you can STILL do this.

interface Group1 {}

class AError extends LetterError implements Group1 {}

class BError extends LetterError implements Group1 {}

And then:

catch (Group1 $e) {}

Using OOP when it comes to exceptions is very powerful. Using things like get_class or instanceof are hacks, and should be avoided if possible.

Another solution I would like to add is putting the exception handling functionality in its own method.

You could have

function handleExceptionMethod1(Exception $e)
{
//voodoo
}

function handleExceptionMethod2(Exception $e)
{
//voodoo
}

Assuming there is absolutely no way you can control exception class hierarchies or interfaces (and there almost always will be a way), you can do the following:

try
{
stuff()
}
catch(ExceptionA $e)
{
$this->handleExceptionMethod1($e);
}
catch(ExceptionB $e)
{
$this->handleExceptionMethod1($e);
}
catch(ExceptionC $e)
{
$this->handleExceptionMethod1($e);
}
catch(Exception $e)
{
$this->handleExceptionMethod2($e);
}

In this way, you are still have a only single code location you have to modify if your exception handling mechanism needs to change, and you are working within the general constructs of OOP.

PHP: exceptions vs errors?

Exceptions are thrown - they are intended to be caught. Errors are generally unrecoverable. Lets say for instance - you have a block of code that will insert a row into a database. It is possible that this call fails (duplicate ID) - you will want to have a "Error" which in this case is an "Exception". When you are inserting these rows, you can do something like this

try {
$row->insert();
$inserted = true;
} catch (Exception $e) {
echo "There was an error inserting the row - ".$e->getMessage();
$inserted = false;
}

echo "Some more stuff";

Program execution will continue - because you 'caught' the exception. An exception will be treated as an error unless it is caught. It will allow you to continue program execution after it fails as well.

Is it possible in PHP to prevent Fatal error: Call to undefined function?

No. Fatal errors are fatal. Even if you were to write your own error handler or use the @ error suppression operator, E_FATAL errors will still cause the script to halt execution.

The only way to handle this is to use function_exists() (and possibly is_callable() for good measure) as in your example above.

It's always a better idea to code defensively around a potential (probable?) error than it is to just let the error happen and deal with it later anyway.

EDIT - php7 has changed this behavior, and undefined functions/methods are catchable exceptions.

Catching Stripe errors with Try/Catch PHP method

I think there is more than these exceptions (Stripe_InvalidRequestError and Stripe_Error) to catch.

The code below is from Stripe's web site. Probably, these additional exceptions, which you didn't consider, occurs and your code fails sometimes.

try {
// Use Stripe's bindings...
} catch(Stripe_CardError $e) {
// Since it's a decline, Stripe_CardError will be caught
$body = $e->getJsonBody();
$err = $body['error'];

print('Status is:' . $e->getHttpStatus() . "\n");
print('Type is:' . $err['type'] . "\n");
print('Code is:' . $err['code'] . "\n");
// param is '' in this case
print('Param is:' . $err['param'] . "\n");
print('Message is:' . $err['message'] . "\n");
} catch (Stripe_InvalidRequestError $e) {
// Invalid parameters were supplied to Stripe's API
} catch (Stripe_AuthenticationError $e) {
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
} catch (Stripe_ApiConnectionError $e) {
// Network communication with Stripe failed
} catch (Stripe_Error $e) {
// Display a very generic error to the user, and maybe send
// yourself an email
} catch (Exception $e) {
// Something else happened, completely unrelated to Stripe
}

EDIT:

try {
$charge = Stripe_Charge::create(array(
"amount" => $clientPriceStripe, // amount in cents
"currency" => "usd",
"customer" => $customer->id,
"description" => $description));
$success = 1;
$paymentProcessor="Credit card (www.stripe.com)";
} catch(Stripe_CardError $e) {
$error1 = $e->getMessage();
} catch (Stripe_InvalidRequestError $e) {
// Invalid parameters were supplied to Stripe's API
$error2 = $e->getMessage();
} catch (Stripe_AuthenticationError $e) {
// Authentication with Stripe's API failed
$error3 = $e->getMessage();
} catch (Stripe_ApiConnectionError $e) {
// Network communication with Stripe failed
$error4 = $e->getMessage();
} catch (Stripe_Error $e) {
// Display a very generic error to the user, and maybe send
// yourself an email
$error5 = $e->getMessage();
} catch (Exception $e) {
// Something else happened, completely unrelated to Stripe
$error6 = $e->getMessage();
}

if ($success!=1)
{
$_SESSION['error1'] = $error1;
$_SESSION['error2'] = $error2;
$_SESSION['error3'] = $error3;
$_SESSION['error4'] = $error4;
$_SESSION['error5'] = $error5;
$_SESSION['error6'] = $error6;
header('Location: checkout.php');
exit();
}

Now, you will catch all possible exceptions and you can display error message as you wish. And also $error6 is for unrelated exceptions.

Try / catch in mysqli

In the first section of code when you use the if statement, you are checking to see if that one condition is true and then outputting your message.

A try catch block essentially works like this

try{
//place code here that could potentially throw an exception
}
catch(Exception $e)
{
//We will catch ANY exception that the try block will throw

}

So you see that while your if statement is checking for a condition that you are anticipating, the try catch block will detect anything that goes wrong, even those things that you don't anticipate.
Therefore, when debugging you can alter the code in the catch block to deal with exceptions as you see fit

See the PHP docs for more information about exceptions
http://php.net/manual/en/language.exceptions.php

Are PHP exceptions really more useful than errors? (Adv)

I believe there is a philosophical difference between the definitions of errors and exceptions.

An error simply put is a programmed flaw, generated by a logical fallacy in the code. Passing strlen() an incorrect number of arguments should naturally be an error. An exception, on the other hand, handles those cases where everything is programmed correctly, but your code is interacting with resources outside of the codebase (filesystem, web service, external executable, etc). While it is expected that such external resources should work perfectly on every call, there will be cases -- out of the scope of your program's control -- that are not attributed to faults of your code (filesystem gets unmounted, connection timeout, etc). Because these issues are due to external factors, they are deemed exceptions.

The main difference is that an error occurs within one's own code, whereas an exception occurs in the case of an anomaly found in a third-party resource.



Related Topics



Leave a reply



Submit