FAQ
Hi!

  The error message that is created for an uncaught exception as well
  as the stacktrace of an exception list the number of the line on which
  the exception object was created. I would expect this to be number of
  the line on which the exception is raised using the throw statement.

  Derick agrees with me that this is a bug. We propose to update the file
  and line properties of the exception object in the
  zend_throw_exception_internal() and zend_throw_exception() functions.

  Would such a change be accepted? Does it require an RFC?

  Thanks!
Sebastian

Search Discussions

  • Stas Malyshev at May 23, 2013 at 8:31 pm
    Hi!
    Derick agrees with me that this is a bug. We propose to update the file
    and line properties of the exception object in the
    zend_throw_exception_internal() and zend_throw_exception() functions.

    Would such a change be accepted? Does it require an RFC?
    On one hand, I think it makes sense - nobody really cares where the
    exception was created... But there's one problem here:

    try {
      //stuff
    } catch(Exception $e) {
      $logger->log("Oops, exception!");
      throw $e;
    }

    If we update file/line here, we lose original exception information and
    file/line in the exception becomes useless. Right now, since 99.99% of
    the code does "throw new", it is always useful. So how you would propose
    to solve this?

    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Hakre at May 23, 2013 at 11:37 pm

    On one hand, I think it makes sense - nobody really cares where the
    exception was created... But there's one problem here:

    try {
    //stuff
    } catch(Exception $e) {
    $logger->log("Oops, exception!");
    throw $e;
    }

    If we update file/line here, we lose original exception information and
    file/line in the exception becomes useless. Right now, since 99.99% of
    the code does "throw new", it is always useful. So how you would
    propose
    to solve this?
    rethrow $e;
  • Stas Malyshev at May 24, 2013 at 12:14 am
    Hi!
    the code does "throw new", it is always useful. So how you would
    propose
    to solve this?
    rethrow $e;
    Yes, this is definitely an option, but requires a new keyword.
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Adam Harvey at May 24, 2013 at 12:39 am

    On 23 May 2013 17:14, Stas Malyshev wrote:
    Hi!
    the code does "throw new", it is always useful. So how you would
    propose
    to solve this?
    rethrow $e;
    Yes, this is definitely an option, but requires a new keyword.
    We could use a C++ style throw; as an implicit rethrow.

    Adam
  • Josh Davis at May 24, 2013 at 2:36 am

    On 23 May 2013 22:22, Stas Malyshev wrote:

    If we update file/line here, we lose original exception information and
    file/line in the exception becomes useless. Right now, since 99.99% of
    the code does "throw new", it is always useful. So how you would propose
    to solve this?
    As a PHP programmer, I would always expect the file/line to refer to
    the throw statement that has thrown it last. If I wanted to keep track
    of an exception being rethrown, I'd use nested exceptions (Exception's
    constructor's third parameter.)

    Hope that helps.
  • Stas Malyshev at May 24, 2013 at 8:44 am
    Hi!
    As a PHP programmer, I would always expect the file/line to refer to
    the throw statement that has thrown it last. If I wanted to keep track
    It is rather surprising that you would expect that as a PHP programmer,
    since it never worked this way in PHP, and no PHP code works this way
    either.

    Also, throwing new exception with previous is not the same as throwing
    the same exception twice.
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Levi Morrison at May 24, 2013 at 2:36 pm

    Also, throwing new exception with previous is not the same as throwing
    the same exception twice.
    Correct, but I've personally never thrown the same exception twice.
    The only times I've thrown exceptions from catch blocks is to provide
    a better exception or perhaps to abstract away something in the
    implementation. For instance, if I hit a PDO exception in my data
    access then I'll catch it somewhere higher in the structure and throw
    a GatewayException instead. Likewise, if the data was coming from The
    Cloud and I couldn't access it for some reason I'd throw the
    GatewayException. This way when someone uses the gateway the
    implementation doesn't leak. This is the only time I've thrown
    exceptions in a catch block.

    This is an interesting 'bug' or 'feature' or whatever you want to call
    it. I wouldn't say the current way is wrong, but a naive approach
    would have some interesting issues as well. More than anything I think
    we just need to decide what we want the behavior to be a document the
    resulting quirks.
  • Etienne Kneuss at May 24, 2013 at 3:44 pm

    On Fri, May 24, 2013 at 10:44 AM, Stas Malyshev wrote:

    Hi!
    As a PHP programmer, I would always expect the file/line to refer to
    the throw statement that has thrown it last. If I wanted to keep track
    It is rather surprising that you would expect that as a PHP programmer,
    since it never worked this way in PHP, and no PHP code works this way
    either.

    Also, throwing new exception with previous is not the same as throwing
    the same exception twice.

    I agree, I think it makes sense to see exceptions as immutable and let
    "new" define the line.

    If you want to rethrow an exception in a different context while keeping
    track of both, I think chaining them is the better approach: throw new
    AnotherException("..", 0, $thepreviousexception);


    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227

    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php

    --
    Etienne Kneuss
    http://www.colder.ch
  • Josh Davis at May 24, 2013 at 3:57 pm

    On 24 May 2013 10:44, Stas Malyshev wrote:
    It is rather surprising that you would expect that as a PHP programmer,
    since it never worked this way in PHP, and no PHP code works this way
    either.
    I'm saying that "as a PHP programmer" because my expectation is not
    based on how other languages work, it's instinctive (perhaps
    influenced by what used to be the method's description.) If I call
    getLine() and I don't think about how other languages handle
    exceptions, and I don't go out of my way to check the manual to see
    whether it's been changed since 5.1, what comes to mind is "this is
    going to tell me where the throw occured."
  • Jared Williams at May 23, 2013 at 11:40 pm

    -----Original Message-----
    From: Sebastian Bergmann
    Sent: 23 May 2013 21:18
    To: internals@lists.php.net
    Subject: [PHP-DEV] Bug #64910: Line number of $e = new
    Exception vs. line number of throw $e

    Hi!

    The error message that is created for an uncaught exception
    as well as the stacktrace of an exception list the number of
    the line on which the exception object was created. I would
    expect this to be number of the line on which the exception
    is raised using the throw statement.

    Derick agrees with me that this is a bug. We propose to
    update the file and line properties of the exception object in the
    zend_throw_exception_internal() and zend_throw_exception()
    functions.
    Would such a change be accepted? Does it require an RFC?
    I agree that it should have been where the throw occurs, to allow for
    an ExceptionFactory type use.

    There is a method of making it better, but it's bit (rather a lot)
    gnarly.

    function createException($errno, $message, Exception $exception =
    null)
    {
       // Please forgive us for what we are about to do.
       // Fix up exceptions so they appear closer to where they are thrown
       $f = Closure::bind(
           function() {
             array_shift($this->trace); // createException_
             $t = array_shift($this->trace); // createException
             $this->line = $t['line'];
             $this->file = $t['file'];
             return $this;
           }, $this->createException_($errno, $message, $exception),
    Exception::class);
       return $f();
    }

    private function createException_($errno, $message, Exception
    $exception = null)
    {
       switch ($errno) {
         case 2002:
           return new ConnectException($message, $errno, $exception);

         case 2013: // Connection dropped.
         case 2006: // Gone away
           return new ConnectionDroppedException($message, $errno,
    $exception);

         /*
         ....
         */

         default:
           return new DatabaseException($message, $errno, $exception);
       }
    }

    So

    throw $obj->createException(...); reports a more useful/accurate
    location.

    Jared

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedMay 23, '13 at 8:18p
activeMay 24, '13 at 3:57p
posts11
users8
websitephp.net

People

Translate

site design / logo © 2019 Grokbase