PHP: \Exception or Exception inside a namespace - php

I am trying to handle some errors in my api. However I tried some so many ways to execute what it's needed to it done?
In the code i used Exception, \Exception, another class extending to Exception, "use \Exception".
None of these options works.
What i need to do execute the block catch?
//Piece of source in the begin of file
namespace Business\Notifiers\Webhook;
use \Exception;
class MyException extends \Exception {}
//Piece of source from my class
try{
$products = $payment->getProducts();
if(count($products) == 0)
return;
$flight_id = $products[0]->flight_id;
$this->message = 'Sir, we have a new request: ';
$products = null; //Chagind it to null to force an error..
foreach($products as $product){
$this->appendAttachment(array(
'color' => '#432789',
'text' =>
"*Name:* $product->name $product->last_name \n" .
"*Total Paid:* R\$$product->price\n",
'mrkdwn_in' => ['text', 'pretext']
));
}
} catch(Exception $e){
$this->message = "A exception occurred ";
} catch(\Exception $e){
$this->message = "A exception occurred e";
} catch(MyException $e){
$this->message = "A exception occurred";
}

The accepted answer above give the real cause of the issue, but did not answer the topic
If in case someone is interested and is looking for
what is the difference between Exception and \Exception inside a namespace?
Still valid against PHP 7.3.5:
\Exception: Refer to Exception in root namespace
Exception: Refer to Exception in current namespace
PHP does not fall back to root namespace, if the class cannot be found in current name space, it emits an error.
<?php
namespace Business;
try {
throw new Exception("X"); // Uncaught Error: Class 'Business\Exception' not found
} catch (Exception $e) {
echo "Exception: " . $e->getMessage();
}
<?php
namespace Business;
class Exception extends \Exception {} // means \Business\Exception extends \Exception
$a = new Exception('hi'); // $a is an object of class \Business\Exception
$b = new \Exception('hi'); // $b is an object of class \Exception

First of all, you need to understand the difference between an exception and an error:
http://php.net/manual/en/language.exceptions.php
http://php.net/manual/en/ref.errorfunc.php
Trying to foreach over a null value will not yield an exception, but trigger an error. You can use an error handler to wrap an error in an exception, as such:
<?php
function handle ($code, $message)
{
throw new \Exception($message, $code);
}
set_error_handler('handle');
// now this will fail
try {
$foo = null;
foreach ($foo as $bar) {
}
} catch(\Exception $e) {
echo $e->getMessage();
}
However in your code, you can simply check if $products is null and if so, throw an exception:
if (!$products) {
throw new \Exception('Could not find any products')
}
foreach($products as $product) { ...

Related

Class not found, when trying to pass class name as string, namespace issue

Here is a method, in which a string is passed, using that string an instance is created. Example method:
public function action($actionType)
{
//var_dump(new $actionType);
if (!class_exists($actionType)) {
//throw new Exception
}
if (!(new $actionType) instanceof ActionInterface) {
////throw new Exception
}
$actionType = new $actionType;
echo $actionType->doAction();
}
But I am getting an error of class not found, however when I manually write the class name or manually append the namespace this way $actionType = __namespace__ . "\\$actionType";, then error goes. Why is that happening?
Try this:
public function action($actionType) {
//var_dump(new $actionType);
if (!class_exists($actionType)) {
//throw new Exception
}
$actionType = new $actionType;
if (!($actionType instanceof ActionInterface)) {
////throw new Exception
}
echo $actionType->doAction();
}

PHP: add a custom method to a(n internal) class (derived from exception class) at runtime

I extended the exception class amongst other things to add a method getMessageHTML().
In my application I want to catch any exception - also exceptions of derived internal classes like e.g. the ReflectionException - and want to be able to use a getMessageHTML() method or other custom methods on any exception and any derived exception.
Is there any way, to add a method or trait to an internal class like the exception class or the ReflectionException class at runtime?
The only solution that comes to my mind is to wrap any catched exception into my extended exception class like:
$anyException = new Exception(); //or ReflectionException, or ...
$wrappedException = MyException::wrap($anyException);
$wrappedException->getMessageHTML(); //or any other custom method
is there any implementation, that allows to introduce a method to every derived internal or foreign class/object, so that any object knows it?
$anyException = new Exception(); //or ReflectionException, or ...
$anyException->getMessageHTML();
then i could simply do:
try
{
throw <anyException>(); //like throw Exception() or throw ReflectionException() ...
}
catch($e)
{
$e->getMessageHTML(); //its assured that the method is known.
}
For now I am doing it like this:
class MyException extends Exception
{
protected static function cast($destination, $sourceObject)
{
if(is_string($destination))
$destination = new $destination();
$sourceReflection = new \ReflectionObject($sourceObject);
$destinationReflection = new \ReflectionObject($destination);
$sourceProperties = $sourceReflection->getProperties();
foreach($sourceProperties as $sourceProperty)
{
$sourceProperty->setAccessible(true);
$name = $sourceProperty->getName();
$value = $sourceProperty->getValue($sourceObject);
if ($destinationReflection->hasProperty($name))
{
$propDest = $destinationReflection->getProperty($name);
$propDest->setAccessible(true);
$propDest->setValue($destination,$value);
}
else
$destination->$name = $value;
}
return $destination;
}
public static function wrap(Exception $exception)
{
$wrap = $exception;
if(!$exception instanceof MyException)
$wrap = self::cast(__CLASS__, $exception);
return $wrap;
}
public function getMessageHTML()
{
//some code ...
}
}
try
{
throw new ReflectionException('test');
}
catch(Exception $e)
{
$e = MyException::wrap($e);
echo $e->getMessageHTML();
}
or - simpler - and with the advantage to have the previous exception available:
class MyException extends Exception
{
public static function wrap(Exception $exception)
{
$wrap = $exception;
if(!$exception instanceof AppException)
{
try
{
throw new AppException($exception->getMessage(), $exception->getCode(), $exception);
}
catch(AppException $e)
{
$wrap = $e;
}
}
return $wrap;
}
public function getMessageHTML()
{
//some code ...
}
}

Uncaught exception with namespace

I am reading a book about php and I found this script that doesn't work:
namespace woo\controller {
// woo\controller\ApplicationHelper;
class ApplicationHelper {
function getOptions() {
if (!file_exists("data/woo_options_not_there.xml")) {
$r = new \woo\base\AppException("Non riesco ad aprire il file<br>");
throw new $r;
}
$options = simplexml_load_file("data/woo_options.xml");
$dsn = (string) $options->dsn;
print $dsn;
}
}
$d = (new ApplicationHelper())->getOptions();
}
namespace woo\base {
class AppException extends \Exception {
}
}
Can you help me?
This is the mistake:
Fatal error: Uncaught exception 'woo\base\AppException' in C:\xampp\htdocs\9781430260318_Chapter_12_Code\listing12.00.php:11 Stack trace: #0 C:\xampp\htdocs\9781430260318_Chapter_12_Code\listing12.00.php(20): woo\controller\ApplicationHelper->getOptions() #1 {main} thrown in C:\xampp\htdocs\9781430260318_Chapter_12_Code\listing12.00.php on line 11
So let's follow the train of logic here
We're creating the class ApplicationHelper and then instantiating it. Then, we call getOptions() which looks for an XML file and, if it doesn't find it, throws an exception.
Your code is working fine, you just forgot to catch the exception (this produces a fatal PHP error)
try {
$d = (new ApplicationHelper())->getOptions();
} catch(\woo\base\AppException $err) {
echo 'Error: ' . $err->getMessage();
}

creating a simple exception for a class

I am creating a class called ex: foo
class foo{
function __construct($arg){
if(empty($arg)){
throw new fooException('argument can not be empty');
}
}
}
I tried to create the class without passing anything through the constructor like this
try{
$o = new foo();
}catch(FooException $e){
echo $e->getMessage();
}
I am getting error Fatal error: Class 'FooException' not found in ..
I realize that, I need to extend maybe the error exception class, but there are no examples on how to do this in SO.
Here's an example of defining a custom Exception called FooException.
The class that follows it, TestException tests this custom exception.
<?php
/**
* Define a custom exception class
*/
class FooException extends Exception
{
// Redefine the exception so message isn't optional
public function __construct($message, $code = 0, Exception $previous = null) {
// some code
// make sure everything is assigned properly
parent::__construct($message, $code, $previous);
}
// custom string representation of object
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "A custom function for this type of exception\n";
}
}
/**
* Create a class to test the exception
*/
class TestException
{
public $var;
const THROW_NONE = 0;
const THROW_CUSTOM = 1;
const THROW_DEFAULT = 2;
function __construct($avalue = self::THROW_NONE) {
switch ($avalue) {
case self::THROW_CUSTOM:
// throw custom exception
throw new FooException('1 is an invalid parameter', 5);
break;
case self::THROW_DEFAULT:
// throw default one.
throw new Exception('2 is not allowed as a parameter', 6);
break;
default:
// No exception, object will be created.
$this->var = $avalue;
break;
}
}
}
// Example 1
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (FooException $e) { // Will be caught
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // Skipped
echo "Caught Default Exception\n", $e;
}
// Continue execution
var_dump($o); // Null
echo "\n\n";
// Example 2
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (FooException $e) { // Doesn't match this type
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // Will be caught
echo "Caught Default Exception\n", $e;
}
// Continue execution
var_dump($o); // Null
echo "\n\n";
// Example 3
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) { // Will be caught
echo "Default Exception caught\n", $e;
}
// Continue execution
var_dump($o); // Null
echo "\n\n";
// Example 4
try {
$o = new TestException();
} catch (Exception $e) { // Skipped, no exception
echo "Default Exception caught\n", $e;
}
// Continue execution
var_dump($o); // TestException
echo "\n\n";
?>
Source: http://www.php.net/manual/en/language.exceptions.extending.php
I modified it for your FooException
I see 2 things here, first, the exception you are throwing is called "fooException", and then, the one you are catching, is called "FooException", this is not correct, maybe a typo?. Another thing is, did you create a class named "FooException" and load it in your application?
require_once(path/to/FooExceptionClass.php);
Hope this helps.

php manual exception example

So I was reading the php manual on Extending Exceptions and read the example code. My question about the following code is: why does var_dump($o) evaluate to null? Is it because the constructor of the class TestException throws an exception, hence not allowing the completion of the object? I am almost certain that is the reason.
Nevertheless here is the code for examination:
<?php
/**
* Define a custom exception class
*/
class MyException extends Exception
{
// Redefine the exception so message isn't optional
public function __construct($message, $code = 0, Exception $previous = null) {
// some code
// make sure everything is assigned properly
parent::__construct($message, $code, $previous);
}
// custom string representation of object
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "A custom function for this type of exception\n";
}
}
/**
* Create a class to test the exception
*/
class TestException
{
public $var;
const THROW_NONE = 0;
const THROW_CUSTOM = 1;
const THROW_DEFAULT = 2;
function __construct($avalue = self::THROW_NONE) {
switch ($avalue) {
case self::THROW_CUSTOM:
// throw custom exception
throw new MyException('1 is an invalid parameter', 5);
break;
case self::THROW_DEFAULT:
// throw default one.
throw new Exception('2 is not allowed as a parameter', 6);
break;
default:
// No exception, object will be created.
$this->var = $avalue;
break;
}
}
}
// Example 1
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) { // Will be caught
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // Skipped
echo "Caught Default Exception\n", $e;
}
// Continue execution
var_dump($o); // Null
?>
Have a look at PHP exception from PHP official site.
Example:
<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
/* rethrow it */
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>

Categories