On 31 December 2015 at 14:52, Junade Ali <m...@junade.com> wrote:
> Hi all;
>
> I am looking to submit an RFC in order to remove the error suppression
> operator in PHP, namely the @ symbol.
>

Hi Junade,


TL:DR - I think just deprecating the silence operator without having a
plan for something better is not going to happen. The below
summarizes/repeats what has been said already, and suggests an
alternative.

------

So, the problem with the silence operator isn't that it exists, it's
that it silences all errors.

@foo();
bar();

This silences all warnings/errors raise by the function 'foo'. Which
is bad because the programmer probably only meant to silence a
specific error or warning.

Converting all the internal warnings and errors to exceptions without
doing anything else is probably not a great idea. Say that foo has two
error conditions which get changed to be two exceptions FileException
and DNSException. The code would now look like:


try {
    foo();
}
catch (FileException $fe) {
    // This is not an error in this situation, execution can continue.
}
catch (DNSException $ne) {
    // This is not an error in this situation, execution can continue.
}
bar();


That is pretty horrific even with just two exceptions. In actual code,
it would be even worse when there are multiple lines that need errors
supprssing. To make it be acceptable, I think what is needed is
somthing like the ability to supprress individual exceptions on a
single line.

// If FileException, NetworkException are thrown inside 'foo',
// they are automatically
// caught and execution continues to call bar()
foo() suppress FileException, NetworkException;
bar();


That would allow people to ignore specific exceptions without having a
huge amount of boilerplate code that makes the actual code illegible.

Possibly a more powerful technique would be needed, e.g.being able to
specific an exception handler on a line by line basis.*


// Execute function foo and if any exception is
// raised, call the callable 'fooCallException'
foo() raise 'fooRaiseException';
bar();

public function fooRaiseException(\Throwable $t)
{
    if ($t instanceof FileException ||
        $t instanceof NetworkException) {
        // This is not an error in this situation, execution can continue.
        return;
    }

    // Other exceptions are not acceptable.
    // Propagation of the exception should continue as normal.
    throw $t
}



The benefits of doing it like this are:

 * Any unexpected exceptions are not silenced. This avoids the problem
of all errors being silenced when the programmer thought only a single
one would be suppressed.

 * It would allow users to debug their code. Even if an error is
suppressed by the raise callable for a line of code, it would still be
userland code that can be stepped through with a debugger, and so you
can see the exception inside the 'raise' function.

 * It leaves the code in a readable state, which having lots of
try/catch blocks does not.

 * It allows separate modules to have their own way of handling
errors, whereas set_error_handler is a per application setting.


As I said at the start, I think we need to have more powerful error
handling in place before deprecating the silence operator. If anyone
wants to progress this RFC, what I think needs to happen is:

* Work on something like the above 'raise' or 'suppress' exceptions so
that there is an alternative to the internal warnings.

* Work on a plan on how to migrate all internal errors/warnings to
individual exceptions. The current way of using set_error_handler to
convert warnings/errors into generic exceptions isn't good enough.
People need file operations to raise a more specific 'FileException',
to allow catching of individual types of error. I don't think it would
be feasible to just have a massive BC break on this...so a cunning
migration plan would be needed.

* Figure out if the silence operator is then no longer needed when
those two are done.

Obviously the removal of the silence operator could only be done at a
major version, however adding the individual 'raise' handling or
allowing users to convert internal warnings/errors to specific
exceptions could be done at minor versions, and probably should be, if
you want to be able to plan to remove the silence operator for PHP
8/9.

cheers
Dan


* This would be similar to Pythons 'temporarily suppressing warnings'
but instead on a line-by-line basis rather than function basis.
https://docs.python.org/2/library/warnings.html

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

Reply via email to