25

Is it possible to add an extra parameter when throwing an exception?

When I throw an exception I send along the error message but I would also like to send along the name of the field in a extra parameter. Something like:

throw new Exception('this is an error message', 'the field');

So when I display the message I can do something like this:

show_error($e->getFieldname, $e->getMessage());
1
  • If you came here looking for how to pass an error code as an extra parameter, note that PHP exceptions already have an optional error code parameter. See php.net/manual/en/exception.getcode.php Commented Dec 28, 2018 at 10:56

4 Answers 4

36

No, you would have to subclass Exception with your own implementation and add that method.

class FieldException extends Exception
{
    protected $_field;
    public function __construct($message="", $code=0 , Exception $previous=NULL, $field = NULL)
    {
        $this->_field = $field;
        parent::__construct($message, $code, $previous);
    }
    public function getField()
    {
        return $this->_field;
    }
}

But actually, I am not a friend of adding methods or properties to Exceptions. An Exception represents just that: something exceptional that happened in your application. The "field" property is really not part of the Exception, but part of the exception message, so I'd probably use a proper message like:

Wrong value for field foo. Excepted string, got integer

Sign up to request clarification or add additional context in comments.

5 Comments

how do i use it? if i do throw new FieldException('message', 'field'); i get Wrong parameters for Exception
@Dazz new FieldMessage('message',0,NULL,'field'). The constructor for exceptions requires the message, but also allows for two optional arguments. Changing the order might break exception handling in complex applications where exceptions are rethrown, so to make sure nothing breaks, you add your param as the fourth (if you use that solution at all)
I had to leave out the Exception $previous part, thats only for php 5.3.0+ and i using 5.2.9. and in the construct $this->field should be $this->_field. Then it works perfect! Tnx
@Dazz good catches! Actually, thinking of it, I am not that sure swapping the argument order will do harm at all. ErrorException has different order too, but all the SplExceptions follow the regular Exception arguments order. You might just as well try. I still think a proper message would be the best option though :)
this extending can be completely valid: you may have created an invoice (for example) that failed. in that instance you would want the PaymentFailedException (say) cause an email in the calling process to go to the customer and to have the $InvoiceId so it can attach it, get the customer details etc
8

There is no need to add an extra parameter.

You can just throw an Exception like this:

throw new Exception("My Exception Text", 1234);

And access both values:

catch (Throwable $t)
{  
    echo var_dump($t);
    echo "Exception: " . $t->getMessage();
    echo "Code: " . $t->getCode();
}

1 Comment

if you just want to set some error code, this solution better
2

What I do, is have a class to create custom exceptions, but to standardise matters, I simply have one additional argument, which is an object (well, so far it's always been an array), which allows me to specify unlimited amount of exception data (much like a javascript exception).

Output:

Fatal error: Uncaught SqlProxyException 'Duplicate entry '1' for key 'PRIMARY'' in     /usr/src/wrangler/trunk/common/SqlProxy.php(356)
#0 /usr/src/wrangler/trunk/common/SqlProxy.php(341): SqlProxy::Update('INSERT into tes...')
#1 /usr/src/wrangler/trunk/common/SqlProxy.php(455): SqlProxy::Insert('INSERT into tes...')
#2 {main}
Array
(
[sql] => INSERT into test SET test='1'
[errorObject] => Array
    (
        [status] => UNKNOWN
        [data] => Array
            (
                [rowsAffected] => -1
                [errorMsg] => Duplicate entry '1' for key 'PRIMARY'
                [errorCode] => 1062
....

This is achieved by the following in my code:

<? require_once "CustomException.php";

## Define the custom exception
class SqlProxyException extends CustomException {}

## Throw a custom exception
throw new SqlProxyException($errorMsg, $errorCode, null, 
    array("sql" => $query, "errorObject" => $result)
);

## Catch the custom exception

try {
   SqlProxy::Insert($argv[2]);
} catch (SqlProxyException $e) {
   fprintf(STDERR, "Fatal error: Uncaught SqlProxyException '%s' in %s(%s)\n%s\n%s\n",
       $e->getMessage(), $e->getFile(), $e->getLine(),
       $e->getTraceAsString(),
       $e->getObject() ? print_r($e->getObject(), 1) : ""
   );
   exit(1);
}  

Not too difficult... and the magic behind CustomException.php is

<?php

interface IException
{
    /* Protected methods inherited from Exception class */
    public function getMessage();                 // Exception message
    public function getCode();                    // User-defined Exception code
    public function getFile();                    // Source filename
    public function getLine();                    // Source line
    public function getTrace();                   // An array of the backtrace()
    public function getTraceAsString();           // Formated string of trace

    /* Overrideable methods inherited from Exception class */
    public function __toString();                 // formated string for display
    public function __construct($message = null, $code = 0);

}

abstract class CustomException extends Exception implements IException
{ 
    protected $message = 'Unknown exception';     // Exception message
    private   $string;                            // Unknown
    protected $code    = 0;                       // User-defined exception code
    protected $file;                              // Source filename of exception
    protected $line;                              // Source line of exception
    protected $object = null;                     // Extra information in an object (array) js style
    private   $trace;                             // Unknown

    public function __construct($message = null, $code = 0, Exception $previous = null, $eventObject = null)
    {
        if (!$message) {
            throw new $this('Unknown '. get_class($this));
        }
       parent::__construct($message, $code, $previous);
       $this->object = $eventObject;
    }

    public function __toString()
    {
        return get_class($this) . " '{$this->message}' in {$this->file}({$this->line})\n"
                                . "{$this->getTraceAsString()}";
    }

   /* Additional custom method */
   public function getObject()                   // Return object (array) of extra info (js style)
   {
      return $this->object;
   }
}

2 Comments

$eventObject should presumably be $object in your constructor (or $object['eventObject'])? Also, overriding/redeclaring the protected properties of the Exception parent class would seem to be unnecessary (in error)?
@w3d good catch on $eventObject. I'm not sure on the matter of redeclaring the properties of Exception. It might be there as ersatz-documentation for the Exception class (or at least, a property list.) If it causes an underlying function of Exception to fail, then it would definitely be in error.
1

You can implement your own Exception class, and customize it.

See Extending Exceptions article for details.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.