Hi all;
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.
I am happy to implement this, although it is merely a concept so far.
My reasons for looking to do this are:
- the error suppression operator leads to developers being lazy about
wrapping things in issets, try/catch blocks or not handling errors correctly - this leads to painful debugging for developers working on projects with
high technical debt - it's slow (though admittedly not that much slower)
- careless error suppression can be reduced by forcing developers to learn
about how to properly handle errors - when the @ symbol is used to prepend database queries, when there is a
genuine error, it can cause the rest of the script to run successfully
causing data integrity issues. If developers were forced to handle errors
correctly this would be less of an issue. - lastly, this operator can lead to scripts dying due to a fatal error
without any explanation of why, leading to painful debugging; all because a
developer was too lazy to wrap a variable in an isset.
Aside from doing this, there are a number of alternatives: re-engineering
the behaviour of the error suppression operator and potentially bringing
into the scope of a function (e.g. silence()); this said, I still feel this
would contain similar issues as it wouldn't address the underlying issues
of lazy error suppression.
Lastly, I recognise this will be a big change to PHP; but I feel it is
necessary to enhance the quality of PHP error handling. Let's not forget
that PHP managed to successfully deprecate the MySQL library.
Looking forward to hearing your thoughts.
Thanks
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.
While few and far between, there are still valid use cases for the
suppression operator, for example when using curl
--
Mark Baker
|. \ -3
|J/ PHP |
|| | __ |
|| |m| |m|
I LOVE PHP
Hi all,
Am 31.12.2015 um 15:52 schrieb Junade Ali:
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.
before you can deprecate the @ operator, there is a lot of work to do
beforehand. A lot of functions print warnings when they fail (in
addition to returning false). All these warnings have to be removed and
put into the matching error()/errno() functions. Before that there is no
way to remove the @ operator. Otherwise you have to disable error
reporting for warnings and that would be far worse than usage of @
currently is.
Greets
Dennis
Le jeu. 31 déc. 2015 à 16:42, Dennis Birkholz php@dennis.birkholz.biz a
écrit :
Hi all,
Am 31.12.2015 um 15:52 schrieb Junade Ali:
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.before you can deprecate the @ operator, there is a lot of work to do
beforehand. A lot of functions print warnings when they fail (in
addition to returning false). All these warnings have to be removed and
put into the matching error()/errno() functions. Before that there is no
way to remove the @ operator. Otherwise you have to disable error
reporting for warnings and that would be far worse than usage of @
currently is.Greets
Dennis
As Dennis said, there is a huge work to be done before that, not that it
shouldn't prevent you from doing that RFC, but this one should therefor
contains a list of all prerequisites and possibly links to all RFCs yours
would depend on.
Cheers,
Patrick
Hi!
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.
I don't think it is a good idea, currently, for the following reasons:
-
A lot of functions produce error messages which may not be important
in specific scenario, and the users should retain control over if they
want them or not. Checking does not solve the problem, because a) it's a
lot of unnecessary boilerplate code and b) the fact that you checked
doesn't mean the situation is the same when you use what you checked -
and race conditions are hard to debug.
For some functions, you may not be even able to predict when they may
output error messages - such as ones relaying them from third-party
library. Of course, better way to handle them would be to return error
status and use error reporting function, or have structured exception
handling (or both) but it's not the case for many existing functions. -
There are scenarios where @ saves a bunch of boilerplate code -
simplest example:
@$counts[$item]++;
vs.
if(!isset($counts[$item])) {
$counts[$item] = 1;
} else {
$counts[$item]++;
}
Now imagine you have to write 20 of those - which is easier to write
and read? Of course, one could argue the notice maybe should not be
produced - but it is.
Aside from doing this, there are a number of alternatives: re-engineering
the behaviour of the error suppression operator and potentially bringing
into the scope of a function (e.g. silence()); this said, I still feel this
would contain similar issues as it wouldn't address the underlying issues
of lazy error suppression.
I don't see how that would achieve anything but making it more verbose.
The inherent problem is that some error reporting is unneeded in some
contexts, while welcome in others. That's the problem that needs
solving, the syntax is secondary to it.
Lastly, I recognise this will be a big change to PHP; but I feel it is
necessary to enhance the quality of PHP error handling. Let's not forget
that PHP managed to successfully deprecate the MySQL library.
PHP did not just remove mysql library, it replaced it with better
alternative. Which was well in place when the talk of the removal
started. I agree that PHP error system could use a lot of improvement -
in fact, it already started with move to exceptions and other changes -
but it has to go much further before we could afford to remove @. I
would say it definitely should not happen anywhere in 7.x line.
--
Stas Malyshev
smalyshev@gmail.com
On Thu, Dec 31, 2015 at 4:10 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:
The inherent problem is that some error reporting is unneeded in some
contexts, while welcome in others. That's the problem that needs
solving, the syntax is secondary to it.
That hits the nail on the head.
When triggered errors are unneeded, @ works beautifully.
When they're needed, use a helper like from my third-party library
https://github.com/haldayne/fox/blob/master/src/CaptureErrors.php to
capture them:
use Haldayne\Fox\CaptureErrors;
$copy = new CaptureErrors(function ($a, $b) { return copy($a, $b); });
$okay = $copy('foo.txt', 'bar.txt');
if (! $okay) {
throw new
RuntimeException($copy->getCapturedErrors()->pop()->get('message'));
}
I am -1 on removing @ for 7.x series. But, I would be in favor of all
changes that remove unnecessary error messages or add functionality to
better work with error messages. In my mind, those are requisite steps
before removing @.
Thanks,
bishop
Hi Bishop,
Bishop Bettini wrote:
I am -1 on removing @ for 7.x series. But, I would be in favor of all
changes that remove unnecessary error messages or add functionality to
better work with error messages. In my mind, those are requisite steps
before removing @.
I agree here.
It'd be nice if we could somehow catch errors in the same way we can
with exception, but we don't have this just now. Problem is a I can't
think of a non-messy way to make this work, at least not without going
through every PHP extension and adding an identifier for different errors.
One improvement, though, might be an @ equivalent that only silences a
certain level of error. It's still too broad, but it's nonetheless
better than the silence-all we have now.
Thanks.
--
Andrea Faulds
https://ajf.me/
Hi Bishop,
I am -1 on removing @ for 7.x series. But, I would be in favor of all
changes that remove unnecessary error messages or add functionality to
better work with error messages. In my mind, those are requisite steps
before removing @.
I am also very much in agreement with this. There are many conditions where a warning or other error is raised with no way to test for the condition that will trigger the error. Before the @ can be removed, either these errors need to be removed or they need to become an exception that can be caught. For example, I have the following code for writing to a non-blocking stream (assume $resource is a stream socket resource and $data is a string):
// Error reporting suppressed since fwrite()
emits E_WARNING
if the pipe is broken or the buffer is full.
$written = @fwrite($resource, $data);
if (false === $written) {
$message = 'Failed to write to stream.';
if ($error = error_get_last()
) {
$message .= sprintf(' Errno: %d; %s', $error['type'], $error['message']);
}
throw new FailureException($message);
}
There is no way of knowing if the stream buffer is full before calling fwrite()
, resulting in a warning and 0 being returned. IMO, just 0 should be returned without issuing a warning.
Aaron Piotrowski
https://trowski.com
@trowski2002
I don't think it is a good idea, currently, for the following reasons:
[::snip::]
It terrifies me to say this, but I completely agree with Stas. ;)
I can't personally remember the last time I used @ in any production
code, but my one-offs are replete with them. It's a quintessentially
PHP feature in its pragmatism.
Okay, I'll put the thesaurus down.
-Sara
I don't think it is a good idea, currently, for the following reasons:
[::snip::]
It terrifies me to say this, but I completely agree with Stas. ;)
I can't personally remember the last time I used @ in any production
code, but my one-offs are replete with them. It's a quintessentially
PHP feature in its pragmatism.Okay, I'll put the thesaurus down.
I'd be quite sad to see @ disappear as well. It was one of PHP's
earliest features and its roots date back to mid-80's DOS batch files
(before 1/3 of this list were born I would guess)
-Rasmus
-----Original Message-----
From: Rasmus Lerdorf [mailto:rasmus@lerdorf.com]
Sent: Tuesday, January 05, 2016 7:28 AM
To: Sara Golemon; Stanislav Malyshev
Cc: Junade Ali; PHP internals
Subject: Re: [PHP-DEV] Deprecation of the Error Control Operator (@
symbol)On Thu, Dec 31, 2015 at 1:10 PM, Stanislav Malyshev
smalyshev@gmail.com wrote:I don't think it is a good idea, currently, for the following reasons:
[::snip::]
It terrifies me to say this, but I completely agree with Stas. ;)
I can't personally remember the last time I used @ in any production
code, but my one-offs are replete with them. It's a quintessentially
PHP feature in its pragmatism.Okay, I'll put the thesaurus down.
I'd be quite sad to see @ disappear as well. It was one of PHP's earliest
features and its roots date back to mid-80's DOS batch files (before 1/3
of
this list were born I would guess)
Same here.
Zeev
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.
Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?
-Sara
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?
And to add to that, we have mechanisms to allow settings to be dialed
one way but not another, so this could be made so that you can always
re-enable suppressed errors, but you can never re-hide them.
(open_basedir does something similar)
-Sara
Hi, chiming in from the side,
Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?
I think this is an excellent compromise worth discussion and can vouch
for usage of this suggestion in our environment, today. I maintain a
shared hosting environment of sorts and have many different developer
groups working in that environment. This is the sort of configuration
we would take advantage of immediately.
Thanks twitter/@Beryllium9 (wherever you are!) + Sara,
--
Dustin Wheeler | Software Developer
NC State University
m: mdwheele@ncsu.edu | w: 5-9786
"If you don't know where you're going, it's easy to iteratively not get there."
Sounds like the xdebug.scream or the Scream PECL extension (
https://pecl.php.net/package/scream) to me.
+1 for baking this functionality into core
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?-Sara
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?
Sounds like the xdebug.scream or the Scream PECL extension (
https://pecl.php.net/package/scream) to me.+1 for baking this functionality into core
That's going to mean an INI setting.. that hosters could abuse. Having
an INI setting like this as part of core is IMO not a great idea.
cheers,
Derick
--
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine
-----Original Message-----
From: Derick Rethans [mailto:derick@php.net]
Sent: Tuesday, January 05, 2016 12:57 PM
To: Michael Heap
Cc: Sara Golemon; Junade Ali; PHP internals
Subject: Re: [PHP-DEV] Deprecation of the Error Control Operator (@
symbol)I am looking to submit an RFC in order to remove the error
suppression operator in PHP, namely the @ symbol.Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?Sounds like the xdebug.scream or the Scream PECL extension (
https://pecl.php.net/package/scream) to me.+1 for baking this functionality into core
That's going to mean an INI setting.. that hosters could abuse. Having
an INI
setting like this as part of core is IMO not a great idea.
I agree. Perhaps through a declare() statement instead? We could easily
make it file-based, so that the declare() statement only affects the local
file, or we could make it global for the entire request.
Zeev
-----Original Message-----
From: Derick Rethans [mailto:derick@php.net]
Sent: Tuesday, January 05, 2016 12:57 PM
To: Michael Heap
Cc: Sara Golemon; Junade Ali; PHP internals
Subject: Re: [PHP-DEV] Deprecation of the Error Control Operator (@
symbol)I am looking to submit an RFC in order to remove the error
suppression operator in PHP, namely the @ symbol.Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?Sounds like the xdebug.scream or the Scream PECL extension (
https://pecl.php.net/package/scream) to me.+1 for baking this functionality into core
That's going to mean an INI setting.. that hosters could abuse. Having
an INI
setting like this as part of core is IMO not a great idea.I agree. Perhaps through a declare() statement instead? We could easily
make it file-based, so that the declare() statement only affects the local
file, or we could make it global for the entire request.Zeev
--
I can't agree more - it's a pain such thing as @ exists.
However we have a bigger issue here - a lot PHP function returns false
AND raises E_WARNING. fopen, fwrite, fread, stream_select.... a lot of
them which I use daily.
Before deprecating @ operator I think we should make a RFC which cover
unified setting to convert all E_* to exceptions (like
PhpWarningException). I know it's just a temporary solution, because
exception should be more specific, but it's a huge amount of work to
replace all errors and warnings with proper exceptions.
Of course it's possible to convert all errors and warnings to
exceptions using set_error_handler()
, but it will be next boilerplate
code for all apps.
--
Cheers,
Grzegorz Zdanowski.
Grzegorz Zdanowski wrote on 05/01/2016 12:27:
Before deprecating @ operator I think we should make a RFC which cover
unified setting to convert all E_* to exceptions (like
PhpWarningException). I know it's just a temporary solution, because
exception should be more specific, but it's a huge amount of work to
replace all errors and warnings with proper exceptions.
This is definitely not the solution. I've seen this suggested a few
times over the years, and every time people seem to miss a vital point:
Warnings are not, in general, a fatal situation. A useful rule of thumb
I heard for "should I throw an exception?" is "would I be happy to use a
die() statement?"
Even if you don't accept that, the main purpose of an exception is to
force the code down a different path. (I've seen lots of discussions
about exceptions being great because they have stack traces, but have
never understood why any other mechanism couldn't also have those).
In a few places, like the file-handle API, the Warning is accompanied by
an invalid return value (usually false) and probably should be an
exception - the code will definitely need to follow a different path,
and dying would often be better than proceeding with an invalid handle
(which will probably end up fatal later).
But in many cases, an E_WARNING
(or an E_NOTICE) really is just a
warning - most code doesn't want to go down an alternative path, but
it might want to log a message. In a few cases, code does want to go
down a different path, and currently has to use the "error handler"
infrastructure. In other cases, code wants to never log the message, and
currently has to use the @ operator.
The main problem, in my opinion, with the current system of "errors"
(better called "messages") is that they provide only two pieces of
identifying information: an integer representing severity, from a small
list; and a string which may have placeholders, may change between
versions, and does not come from a documented list. This means you can
say "suppress everything with E_NOTICE
severity" but not "suppress all
array-assignment warnings"; and you can set up an error handler to
convert everything into exceptions, but a handler to convert all
file-handle warnings into exceptions would have to pattern-match every
message string to identify them.
The only way out of this that I can see is to replace the current
string-based internal message APIs with something that forces the
extension developer to pre-define a set of codes, and provide the
substitution parameters for the error directly. This could then allow
more information to be exposed to userland, and more granular stacking
of handlers and configuration to mask off different types based on their
codes.
Regards,
Rowan Collins
[IMSoP]
From: Derick Rethans [mailto:derick@php.net]
That's going to mean an INI setting.. that hosters could abuse.
Having an INI setting like this as part of core is IMO not a great idea.
I honestly don't understand why that's a bad idea. There are a LOT of
settings that hosters could abuse, but as a general rule they don't,
because it breaks client apps and clients leave.
A hoster could just as easily install XDebug and turn that setting on.
Are they doing that?
Or are you, Derick Rethans, suggesting that installing XDebug is a bad idea? ;)
I agree. Perhaps through a declare() statement instead? We could easily
make it file-based, so that the declare() statement only affects the local
file, or we could make it global for the entire request.
Eh, feels very tomato-tomato to me. Trading in a line in
php.ini/.htaccess/index.php for a line in index.php. Ultimately I'm
the wrong person to defend this since I don't personally have a need
for it, I was just trying to offer compromises.
For context, I do believe the person suggesting it was thinking in
terms of "Finding that fatal error that's been supressed."
-Sara
From: Derick Rethans [mailto:derick@php.net]
That's going to mean an INI setting.. that hosters could abuse.
Having an INI setting like this as part of core is IMO not a great idea.I honestly don't understand why that's a bad idea. There are a LOT of
settings that hosters could abuse, but as a general rule they don't,
because it breaks client apps and clients leave.A hoster could just as easily install XDebug and turn that setting on.
Are they doing that?Or are you, Derick Rethans, suggesting that installing XDebug is a bad idea? ;)
On a production environment, certainly not a good idea.
cheers,
Derick
Hi Sara,
Sara Golemon wrote:
I am looking to submit an RFC in order to remove the error suppression
operator in PHP, namely the @ symbol.Forwarding a suggestion twitter/@Beryllium9:
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?
I don't think that would work out too well. Remember that many projects
have error handles which convert all errors to exceptions: if you
disable @ in those projects, wouldn't their code break?
Thanks.
Andrea Faulds
https://ajf.me/
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?I don't think that would work out too well. Remember that many projects have
error handles which convert all errors to exceptions: if you disable @ in
those projects, wouldn't their code break?
Nope.
Supressed errors already reach custom error handlers: https://3v4l.org/TG8aA
-Sara
How about a global "disable error suppression" setting? That way a
project lead could enforce it for their codebase (and guarantee that
devs "aren't lazy"), but PHP doesn't lose its pragmatism?I don't think that would work out too well. Remember that many projects
have
error handles which convert all errors to exceptions: if you disable @ in
those projects, wouldn't their code break?Nope.
Supressed errors already reach custom error handlers:
https://3v4l.org/TG8aA
sure and most projects check the error_reporting()
level against the $errno
like in the manual:
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}
@ changes the error_reporting()
level for that particular call, so those
custom error handler won't throw exceptions for the suppressed errors but
when you remove/nop @ their code would throwing stuff left and right.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
I don't think that would work out too well. Remember that many projects
have
error handles which convert all errors to exceptions: if you disable @
in
those projects, wouldn't their code break?Nope.
Supressed errors already reach custom error handlers:
https://3v4l.org/TG8aAsure and most projects check the
error_reporting()
level against the $errno
like in the manual:
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}@ changes the
error_reporting()
level for that particular call, so those
custom error handler won't throw exceptions for the suppressed errors but
when you remove/nop @ their code would throwing stuff left and right.
Today I learned... Okay, def a problem (for a specific set of
circumstances). And one which makes me more amenable to Ze'ev
declare() suggestion (on a per-request bases, not per-file) as anyone
modifying a project's codebase for testing can also modify it to
suppress those exceptions as needed and/or just not enable the custom
error handler.
-Sara
I don't think that would work out too well. Remember that many projects
have
error handles which convert all errors to exceptions: if you disable @
in
those projects, wouldn't their code break?Nope.
Supressed errors already reach custom error handlers:
https://3v4l.org/TG8aAsure and most projects check the
error_reporting()
level against the $errno
like in the manual:
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}@ changes the
error_reporting()
level for that particular call, so those
custom error handler won't throw exceptions for the suppressed errors but
when you remove/nop @ their code would throwing stuff left and right.Today I learned... Okay, def a problem (for a specific set of
circumstances). And one which makes me more amenable to Ze'ev
declare() suggestion (on a per-request bases, not per-file) as anyone
modifying a project's codebase for testing can also modify it to
suppress those exceptions as needed and/or just not enable the custom
error handler.
Exactly. There’s no need for a new ini setting, since an error handler can be written that ignores the current error level and throws an exception or does whatever the coder wants.
Abuse is the only real problem with the @ operator. Coders use it in place of proper state or error checking. However, there are legitimate uses such as with fwrite, fopen, stream_select, etc. that Grzegorz Zdanowski and I pointed out. Before anything can be done with the @ operator, changes will need to be made to remove warnings for conditions that the code has no way of checking prior to calling these functions. Setting a custom error handler before calling these functions and removing the error handler afterwards is a clunky solution. Any proposal to remove the @ operator needs to address how functions issuing unavoidable warnings will be changed.
Aaron Piotrowski
https://trowski.com
@trowski2002
Before anything can be done with the @ operator, changes will need to
be made to remove warnings for conditions that the code has no way of
checking prior to calling these functions.
I'd include pragmatism in that calculus. fopen()
can technically be
safely called, but only by adding a lot of boilerplate that makes code
ugly. An @ suppression is perfectly reasonable provided the return
value is sanity checked.
-Sara
Before anything can be done with the @ operator, changes will need
to be made to remove warnings for conditions that the code has no
way of checking prior to calling these functions.I'd include pragmatism in that calculus.
fopen()
can technically be
safely called, but only by adding a lot of boilerplate that makes code
ugly.
And susceptible to race conditions.
cheers,
Derick
Ferenc Kovacs wrote on 05/01/2016 18:09:
sure and most projects check the
error_reporting()
level against the $errno
like in the manual:
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}@ changes the
error_reporting()
level for that particular call, so those
custom error handler won't throw exceptions for the suppressed errors but
when you remove/nop @ their code would throwing stuff left and right.
I'm lost - how does this validate the claim that building scream mode
into core would lead to problems? We already have an ini setting which
can change the error_reporting level, so any error handler relying on
that is already subject to different behaviour in different
environments. Any codebase which wants to ignore the settings of the
environment would surely already omit that boilerplate, and thus be
unaffected by the presence or functionality of the @ operator.
Regards,
Rowan Collins
[IMSoP]
@ changes the
error_reporting()
level for that particular call, so those
custom error handler won't throw exceptions for the suppressed errors but
when you remove/nop @ their code would throwing stuff left and right.I'm lost - how does this validate the claim that building scream mode into
core would lead to problems? We already have an ini setting which can change
the error_reporting level, so any error handler relying on that is already
subject to different behaviour in different environments. Any codebase which
wants to ignore the settings of the environment would surely already omit
that boilerplate, and thus be unaffected by the presence or functionality of
the @ operator.
Because no matter how high your error_reporting is set (globally,
per-dir, or ini-set) the @ suppression operator temporarily resets it
to zero. In psuedo-code the following two blocks are equivalent:
@foo();
if (ini_get('scream')) {
$old_reporting = error_reporting(0);
}
foo();
if (ini_get('scream')) {
error_reporting($old_reporting);
}
So the argument being made is that being able to disable @ suppression
means ignoring whatever value the developer/admin has set for
error_reporting.
-Sara (not taking a stand on whether that's a compelling argument,
just clarifying it)
So the argument being made is that being able to disable @ suppression
means ignoring whatever value the developer/admin has set for
error_reporting.
Sure, that's what the setting would mean; just as setting
error_reporting means ignoring somebody else's value of error_reporting.
I don't see how that's an untintended consequence, or what it's got to
do with choosing between declare() and ini_set()
. Or maybe I'm just
mudding multiple sub-threads now?
Regards,
--
Rowan Collins
[IMSoP]
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
Hi Dan,
// 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.
I like this suggestion a lot, it keeps the expected suppressions with the
call that will be suppressing.
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
}
I'm not sure I like this, because of a few things, it puts the suppressed
exceptions in a separate location from the call getting suppressed. Also,
having the function name as a string will make it harder to find in an IDE
since go to definition won't work (and since functions aren't first class
citizens as in javascript, we can't pass a raw name AFAIK) and admittedly
this reasoning doesn't count, IDE makers can update their IDE to have go to
definition work on strings after a raise keyword (however, this will get
complicated if ANY callable works, IE ['class','method'] and
'class::method'). Its basically moving the boilerplate you didn't like into
a function not connected to the call and allows accidental control flow
changes. Think if I do "foo() raises 'fooRaiseException'" everywhere I call
foo, but then in one place I need to suppress FileException and somewhere
else I don't want to. Someone comes along and changes the fooRaiseException
function and now the place where we need to know about FileException we no
longer do. This is caused by 2 things: the "handler" for the exceptions
isn't tied to the location where the exceptions happen, and "Find Usages"
in an IDE will not find strings referencing the function (especially if
built programmatically), again this second one is not valid because we
shouldn't make decisions based on what IDEs support but what's best for the
language. However I think its important to know the number of changes which
will be required in IDEs to make the feature usable for the average
developer (especially if someone from PHPStorm, NetBeans or ZendStudio came
along and said it would be impossible to support a specific new feature in
a usable way).
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.
And what is the benefit of having either of these options being part of the
language (IIUC, this would mean changes to the parser, lexer, compiler and
run time) when it could be implemented in userland?
function tryAndSuppress(callable $func, array $args = [], array $suppress =
[])
{
try {
$ret = call_user_func_array($func, $args);
} catch (Throwable $e) {
foreach ($suppress as $type) {
if ($e instanceof $type) {
return;
}
}
throw $e;
}
return $ret;
}
$fh = tryAndSuppress('fopen', ['/path/to/some/file.ext', 'r'],
['FileNotFoundException']);
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.
Agree with this 100%. While I think errors suck and should all be turned
into exceptions, I also think the exceptions used need to be meaningful.
~ Ryan
Hi Dan,
having the function name as a string will make it harder to find in an IDE
since go to definition won't work (and since functions aren't first class
citizens as in javascript, we can't pass a raw name AFAIK)
Yes, this is a limition of PHP currently. As it does keep coming up I
think this is something that needs to be addressed, but would need to
be done in a separate RFC.
For this particular case, I don't think it should be a problem. The
IDE should be able to know that the handler is a callable as that is
the only thing that would be allowed there.
And what is the benefit of having either of these options being part of the language
Er......I don't think implementing it in userland like you sugggest is
workable. It would mean calling code would look like:
tryAndSuppress('mkdir', ['/path/to/some', 0755, true], ['IOException']);
$fh = tryAndSuppress('fopen', ['/path/to/some/file.ext', 'r'],
['FileNotFoundException']);
for almost all code, which looks horrible, and breaks all static analysis tools.
in one place I need to suppress FileException and somewhere
else I don't want to.
If/when I write this up as an RFC, I'm going to suggest having two
built-in functions that make it easy and safe to do the normal things
that code does over and over again; convert a generic exception type
to a more specific one, and suppress certain exceptions. See below for
outline implementations of those two functions.
Someone comes along and changes the fooRaiseException
function and now the place where we need to know about FileException we no
longer do.
I know what you mean, but the same is true of all code that is not
called directly. For example in routing for HTTP applications, the
routes are setup and then called dynamically. Yes, if someone changes
what the code does in the callable, then what the application does
changes. Additionally with the 'suppress' and 'convert' function
below, then most people shouldn't need need to use custom functions.
But also, in general, I think it's a mistake to limit the power of a
programming langauge to make in universally safe to use. At least to
some extent, if a feature can never be misused, then it's probably not
powerful enough. Stuff needs to be safe to use by default, but if
people want to do crazy stuff, we shouldn't delibrately stop them aka
“You can't give her that!' she screamed. 'It's not safe!'
IT'S A SWORD, said the Hogfather. THEY'RE NOT MEANT TO BE SAFE.
'She's a child!' shouted Crumley.
IT'S EDUCATIONAL.
'What if she cuts herself?'
THAT WILL BE AN IMPORTANT LESSON.”
― Terry Pratchett, Hogfather
cheers
Dan
This is some example code, that uses the suppress and convert
functions below to suppress any IOException raised by mkdir, and then
convert and IOException generated by file_put_contents into a
SavingDataException
function saveData($directoryName, $data) {
// If the directory already exists, that is
mkdir($directoryName, 0755, true) raise suppress("IOException");
// Actually write the data. Failure to save gets converted
// into a SavingDataException
file_put_contents($directoryName."/foo.txt", $data) raise
convert("SavingDataException", "IOException");
}
// Returns a closure that suppresses any exception that matches
// the listed types.
function suppress(...$suppressedExceptions) {
$fn = function (\Throwable $t) use ($suppressedExceptions) {
foreach ($suppressedExceptions as $suppressedException) {
if (is_a($t, $suppressedException) === true) {
return;
}
}
throw $t;
};
return $fn;
}
// Returns a closure that converts all exceptions that are listed
// into a new exception of the type '$newException'Type with the previous
// exception set as the 'previous exception'.
function convert($newExceptionType, ...$exceptionTypes) {
$fn = function (\Throwable $t) use ($exceptionTypes) {
foreach ($exceptionTypes as $exceptionType) {
if (is_a($t, $exceptionType)) {
throw new $newExceptionType(
$t->getMessge(),
$t->getCode(),
$t
);
}
}
throw $t;
};
return $fn;
}
Dan Ackroyd wrote on 06/01/2016 17:12:
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.
Again, you're focussing exclusively on that sub-set of warnings which
are actually errors in disguise.
I think it would be perfectly reasonable to implement a new file
handling API, which behaves like modern PHP (objects, exceptions, etc)
rather than being a thin wrapper for C (which is why fopen()
does what
it does). There'd then be no particular need to "suppress" any
exceptions thrown from that, because if the handle is invalid, you
actually need to do something different in the catch clause. In the
current C-based API, the "catch" is the "if ( $fh === false )"; the
warning is actually superfluous, hence the desire to suppress it.
But this doesn't actually present a solution to the dozens of other
warnings and notices. It doesn't do anything to help Stas's example for
instance:
@$counts[$item]++;
This is not something which should ever throw an exception, however easy that exception was to discard.
On the other hand, the "suppress" operator might be usable in conjunction with categorised warnings; e.g.
$counts[$item]++ suppress ET_ARRAY_NOSUCHKEY;
I would also contend that a correctly thrown exception should never be something you want to just suppress - at the very least, you want to log it, and probably you want to skip or add some logic. For instance, this makes no sense to me:
$db = new PDO($dsn) suppress PDO_Exception;
// oops, now I have to check if $db instanceof PDO, rather than just jumping to catch/finally
@ doesn't suppress exceptions, nor does it stop fatal errors being fatal; nor should its replacement.
Regards,
Rowan Collins
[IMSoP]
It doesn't do anything to help Stas's example for instance:
@$counts[$item]++;
I think that that code is bogus since the release of PHP 7, which made
it trivial to not use the error suppression for this case, while still
writing code that doesn't take up multiple lines.
$counts[$item] ?? $counts[$item] = 1 ?? $counts[$item]++;
Yes - it's a few more characters but it has another benefit:
This is not something which should ever throw an exception,
Oh yes, it definitely should:
$item = new StdClass;
@$counts[$item] = "This is a bad use of error suppression.";
There is no insertion, because arrays don't support object keys. The
operation completly failed and so there should be an exception.
Currently that code fails silently.
I think it would be perfectly reasonable to implement a new file handling API, which behaves like
modern PHP (objects, exceptions, etc) rather than being a thin wrapper for CI would also contend that a correctly thrown exception should never be
something you want to just suppress
I very much look forward to seeing your proposal for this file
handling API, which is both easy to use, and never throws exceptions
which people will want to discard.
cheers
Dan
Dan Ackroyd wrote on 08/01/2016 16:26:
It doesn't do anything to help Stas's example for instance:
@$counts[$item]++;
I think that that code is bogus since the release of PHP 7, which made
it trivial to not use the error suppression for this case, while still
writing code that doesn't take up multiple lines.$counts[$item] ?? $counts[$item] = 1 ?? $counts[$item]++;
It's a matter of code style; to me, that's still just noise. If I know
that $counts is being used as a "hash" (arbitrary keys, defined on
demand) and not a "struct" (pre-defined keys, accessed dynamically) then
the first version does exactly what I want it to, and I see no advantage
in making it more complex.
This is not something which should ever throw an exception,
Oh yes, it definitely should:$item = new StdClass;
@$counts[$item] = "This is a bad use of error suppression.";There is no insertion, because arrays don't support object keys. The
operation completly failed and so there should be an exception.
Currently that code fails silently.
OK, fine, let me reword that: the warning "undefined index 'foo'" should
never be thrown as an exception.
I am absolutely not saying that there aren't cases where we should be
throwing Exceptions (or Errors, now they exist) rather than Warnings,
just that there are also cases where warnings are non-fatal, and have
nothing in common with Exceptions.
The point of the example is not that the @ operator is perfect here,
it's that sometimes, the ability to suppress specific warnings as "I
know and don't care" is useful. I just wanted to get people away from
the example of fopen()
which frankly should never be raising a warning
in the first place.
I very much look forward to seeing your proposal for this file
handling API, which is both easy to use, and never throws exceptions
which people will want to discard.
I detect sarcasm here, and would like to hear a non-sarcastic version of
your point. Can you give an example of an operation where it would be
reasonable to throw an exception, but also reasonable (and common enough
to affect the design of the API) to completely ignore that exception and
carry on?
If an operation has fatally failed (such as trying to open a
non-existent file for reading), people will want to have code handling
that failure, so suppressing the exception would be counter-productive;
if an operation has encountered an unexpected but non-fatal condition,
it should signal that with something other than an exception (for
instance, returning a success boolean or status flag).
Regards,
Rowan Collins
[IMSoP]
I detect sarcasm here, and would like to hear a non-sarcastic version of
your point.
You're suggesting that we solve a problem in a way that pretty much
every other attempt to do has failed.
I'm not going to be able to point to a single reason why attempting
that solution is not going to work, as the problem comes from the
result of many small problems, none of which are a complete show
stopper individually.
But what you're doing is saying "Why don't we solve it like this? I
can't see how difficult it could be". It's a tactic that has(, even if
you didn't mean to,) a tendency to shut down a particular conversation
until another branch of the conversation has been pursued.
I do encourage you to try to attempt to make that API - it's only by
encountering all of the small problems that you can realise that
although they are not perfect, exceptions allow much nicer APIs than
error checking. Or alternatively you might prove me wrong! and we end
up with a much better solution!
if an operation has encountered an unexpected but non-fatal condition,
it should signal that with something other than an exception (for
instance, returning a success boolean or status flag).
This is a big bit of the problem. Having to remember to check for
errors make the api difficult to use.
If you ever forget to check for an error condition, then you have a
bug in your code. And people are not perfect, so people forget
stuff....which is a bad start.
And it gets really annoying when there are multiple error states e.g.
for mkdir the operation can fail because:
- The directory already exists.
- The program doesn't have permission to create the directory.
- You're trying to create a sub-directory of a directory that doesn't
exist and forgot to set the '$parent = true' flag.
So, now the programmer needs to be able to query what type of error happened.
But worse than that, what happens when there is a new error condition
is added to any function?
All code that was written before the new error condition was added
needs to be updated to check for the new error condition.
Exceptions don't have these problems.
If you forget to try/catch an exception it bubble up and fatals your
program, which is much better than continuing in an unknown error
state.
Individual error conditions can throw separate sub-types of
exceptions, that indicate exactly what error condition occured, which
is a very convenient way of allowing people to declare "These are the
type of errors I can handle, all others I can't".
If an new exception can be thrown from a function, then all existing
programs continue to work as before. Again, if that new error
condition is met, an exception is thrown, rather than blindly
continuing in an error condition.
Aka with exceptions, people writing code can say "These are the
exceptions I can handle, all other error conditions are errors",
whereas the logic is reversed for checking errors where it is a case
of a user saying "These are the error conditions that need to fatal,
all others are fine".
Can you give an example of an operation where it would be
reasonable to throw an exception, but also reasonable (and common enough
to affect the design of the API) to completely ignore that exception and
carry on?
mkdir is a great example of something that has multiple error
conditions. If you're trying to create a uniquely named directory,
then the failure to create it is an error. If you want to just ensure
a directory exists before putting a uniquely named file inside that
directory, then the failure to create the directory through mkdir is
not an error condition.
As I said, this is not a water-tight argument against what you're
suggesting. But saying it's "perfectly reasonable to implement"
something in a way that every other attempt has failed....and not
giving any details of how it would actually work, is not a fantastic
contribution to a discussion.
cheers
Dan
Dan Ackroyd wrote on 08/01/2016 18:44:
You're suggesting that we solve a problem in a way that pretty much
every other attempt to do has failed.
I'm not sure where you got the idea that I was suggesting anything of
the sort.
it's only by
encountering all of the small problems that you can realise that
although they are not perfect, exceptions allow much nicer APIs than
error checking.
I think you've completely misread what I said; here it is for reference:
I think it would be perfectly reasonable to implement a new file
handling API, which behaves like modern PHP (objects, exceptions, etc)
I am advocating for the use of exceptions in that particular case.
What I was saying, however, is that the question of how fopen()
should
signal failure is not the same question as how PHP should signal
warnings. Since this discussion was about warnings, I was trying to move
the discussion away from its focus on one set of APIs.
If you forget to try/catch an exception it bubble up and fatals your
program, which is much better than continuing in an unknown error
state.
You're preaching to the choir here - I know exceptions are absolutely
the right thing in many cases, and use them lots in my own code.
I also know that they are not suited to every situation, and that "if
you don't tell me otherwise, I will halt your program" is sometimes
massive overkill.
I think we're just talking completely at cross-purposes here; I'm not
entirely sure what you thought I was advocating, but what I was actually
saying is really simple:
Exceptions are not the right solution to all the places that PHP
currently has warnings, so a simplified catch statement ("suppress
Exception") is not the right replacement for the @ operator.
Regards,
Rowan Collins
[IMSoP]
Hi!
$counts[$item] ?? $counts[$item] = 1 ?? $counts[$item]++;
This looks completely unreadable and I do not think it works:
https://3v4l.org/PlAHH
Seems to leave $counts as 1 always. But even if it didn't, I would never
pass that on code review - it is very hard to understand what's going on
and it is incredibly easy to break it. Doing such stuff is definitely
not the solution, if you hate @, then if() is way better, at least it's
clear.
$item = new StdClass;
@$counts[$item] = "This is a bad use of error suppression.";There is no insertion, because arrays don't support object keys. The
operation completly failed and so there should be an exception.
No, there should not. If somebody tries to count garbage, I just don't
want to count it. I don't care about it, it's garbage.
Currently that code fails silently.
And that is exactly what I want it to do. Sometimes silent failure is
good, I don't want to know about every little thing that could go
wrong, I just want what's right to be done.
Of course, your intent may be the opposite - but that's exactly the
point, there's more than one use case.
Stas Malyshev
smalyshev@gmail.com
On Fri, Jan 8, 2016 at 11:21 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:
Hi!
$counts[$item] ?? $counts[$item] = 1 ?? $counts[$item]++;
This looks completely unreadable and I do not think it works:
https://3v4l.org/PlAHH
Seems to leave $counts as 1 always. But even if it didn't, I would never
pass that on code review - it is very hard to understand what's going on
and it is incredibly easy to break it. Doing such stuff is definitely
not the solution, if you hate @, then if() is way better, at least it's
clear.$item = new StdClass;
@$counts[$item] = "This is a bad use of error suppression.";There is no insertion, because arrays don't support object keys. The
operation completly failed and so there should be an exception.No, there should not. If somebody tries to count garbage, I just don't
want to count it. I don't care about it, it's garbage.
I agree with Dan on this one. Trying to use an invalid type as a key should
produce something. Your argument that its garbage and you don't care may be
valid for a specific use case, but it may also be a bug in another case.
IE: it wasn't supposed to be an object, and the wrong variable was used,
but tracking down that error if nothing is produced when doing something
defined as invalid will be hard. If you don't want to count garbage, then
you should use if()
if (!is_garbage($key)) @$count[$key]++;
Currently that code fails silently.
And that is exactly what I want it to do. Sometimes silent failure is
good, I don't want to know about every little thing that could go
wrong, I just want what's right to be done.
Of course, your intent may be the opposite - but that's exactly the
point, there's more than one use case.Stas Malyshev
smalyshev@gmail.com
Ryan Pallas wrote on 08/01/2016 18:29:
I agree with Dan on this one. Trying to use an invalid type as a key
should produce something. Your argument that its garbage and you don't
care may be valid for a specific use case, but it may also be a bug in
another case
But that has nothing to do with using exceptions rather than some other
mechanism. I am completely in favour of making warnings better
categorised, and easier to handle, but exceptions are not the way to do
that. It's a case of seeing nails because you're holding a hammer -
exceptions exist, so people want to use them everywhere.
Regards,
Rowan Collins
[IMSoP]
Hi!
when doing something defined as invalid will be hard. If you don't want
to count garbage, then you should use if()if (!is_garbage($key)) @$count[$key]++;
And if you want to check, just do:
if (is_garbage($key)) { throw Exception("Garbage!"); }
Except in this case you know what's going on and when the exception is
thrown and can do what you like, instead of your code just blowing up
randomly with no warning. Or, alternatively, having to check for an
exception each time you do an array access.
--
Stas Malyshev
smalyshev@gmail.com
Hi!
This looks completely unreadable and I do not think it works:
https://3v4l.org/PlAHH
Seems to leave $counts as 1 always. But even if it didn't, I would never
pass that on code review - it is very hard to understand what's going on
and it is incredibly easy to break it.
Apologies, it should be:
$counts[$item] = ($counts[$item] ?? 0) + 1;
Which both works, and to me, is more readable than the @ version, as
it doesn't rely on the person reading it knowing what the magic
behaviour PHP has when using an array that has not been set.
it is very hard to understand what's going on
and it is incredibly easy to break it.
You've had many years getting used to the current way of doing things.
At some point you should try to get used to new features.
And that is exactly what I want it to do. Sometimes silent failure is
good, I don't want to know about every little thing that could go
wrong, I just want what's right to be done.
Of course, your intent may be the opposite - but that's exactly the
point, there's more than one use case.
Yes, yes, totally agreed. Sometimes you just want to be able to tell
the computer, "I know what I'm doing, don't nag" which is why the @ is
great, even though what it does might still use some improvement.
cheers
Dan
Dan Ackroyd wrote on 08/01/2016 18:36:
Apologies, it should be:
$counts[$item] = ($counts[$item] ?? 0) + 1;
Which both works, and to me, is more readable than the @ version
As with the file-manipulation functions, I think you're focussing too
much on the specific example and not on the general principle.
If we go through every single Notice and Warning discussing its
implications, when you might want to suppress it, when it should be
considered fatal, etc, we'll be here forever.
If there is even one Notice or Warning which is - subjectively - (a)
useful, and (b) non-fatal if ignored, then "turn everything into an
exception" is not a complete solution.
Regards,
Rowan Collins
[IMSoP]