Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error and warning IDs #14093

Open
p5pRT opened this issue Sep 16, 2014 · 28 comments
Open

Error and warning IDs #14093

p5pRT opened this issue Sep 16, 2014 · 28 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 16, 2014

Migrated from rt.perl.org#122794 (status was 'open')

Searchable as RT122794$

@p5pRT
Copy link
Author

p5pRT commented Sep 16, 2014

From @cpansprout

As has been oft repeated, we need error codes or IDs to identify diagnostic messages without having to use regular expressions on the message, whose wording might change between versions.

The usual proposed solution is to use error objects. I am opposed to that, because it will break backward compatibility with code that does this​:

if (ref $@​) {
  # ... handle custom error ...
}
else {
  die $@​;
}

(And I’ve seen plenty of code that does that.)

Last year (I think) I proposed implementing them similarly to vstrings. Have just ‘plain’ strings passed around, but with magic attached to them, so that error​::code($@​) or error​::id($@​) will be able to tell us where it originated.

That idea was shot down immediately as making strings ‘more complex’, and since we have objects for this purpose we might as well use them. (See above, how the latter will break things.)

However, I think the magic implementation could just be an implementation detail.

I have long wanted diagnostics.pm to have a ‘splain’ function that will be able to describe a message for me, instead of requiring me to use warn hooks or pipe error messages to the ‘splain’ program.

The thing is, we already have such functionality available; we just need to expose it better.

Put two ideas together and we come up with this​: The functions we provide for identifying a message (error​::code or error​::id, whichever you prefer) could work like diagnostics.pm (i.e., matching the text), but the messages generated by perl could have magic attached to them storing the ID for efficiency. To the Perl programmer, the difference between "Bad hash at foo line 1.\n" from a string literal or input and the same string from $@​ can be transparent. error​::code is just more efficient on the latter.

All error codes should ideally be alphanumeric, to keep them memorable. I would hate having to write ‘no warnings "97"’ to disable a specific warning. Since we already have warning categories, let’s do "category​::shortid". I’m not sure whether we should categorize errors.

Perhaps we should also provide a constructor to allow users to create error objects via error->new(message => xxxx, id => xxx, line => xxx, file, => xxx). error​::code() would take objects and strings.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 16, 2014

From perl5-porters@perl.org

I wrote​:

As has been oft repeated ...
... error​::code is just more efficient on the latter

And it stops there. Somehow the message sent to the list has been truncated. The full version can be seen in the RT ticket.

@p5pRT
Copy link
Author

p5pRT commented Sep 16, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Sep 16, 2014

From @karenetheridge

On Tue, Sep 16, 2014 at 11​:05​:14PM -0000, Father Chrysostomos wrote​:

And it stops there. Somehow the message sent to the list has been truncated. The full version can be seen in the RT ticket.

I posted my thoughts on the wrong thread. I've had a mental image of error
strings from core behaving much like $! does -- the actual error is an
integer, but has a magic locale-aware stringification attached.

Therefore, code like this will behave the same as before​:

  eval { foo() } or warn "got error​: $@​";

but code like this can be smarter​:

  use Try​::Tiny;
  try { foo() }
  catch { # $@​ is now in $_
  create_file() if $_ == EFILENOTFOUND;
  create_dir() if $_ == EDIRNOTFOUND;
  ...
  };

This would make a *lot* of code simpler (with the exception of having to
cope with back-compatibility, alas). The very first example I have at the
top of my mind is​:
https://metacpan.org/source/ZEFRAM/Module-Runtime-0.014/lib/Module/Runtime.pm#L378

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @demerphq

On 17 September 2014 01​:00, Father Chrysostomos <perlbug-followup@​perl.org>
wrote​:

# New Ticket Created by Father Chrysostomos
# Please include the string​: [perl #122794]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=122794 >

As has been oft repeated, we need error codes or IDs to identify
diagnostic messages without having to use regular expressions on the
message, whose wording might change between versions.

The usual proposed solution is to use error objects. I am opposed to
that, because it will break backward compatibility with code that does this​:

if (ref $@​) {
# ... handle custom error ...
}
else {
die $@​;
}

(And I’ve seen plenty of code that does that.)

Last year (I think) I proposed implementing them similarly to vstrings.
Have just ‘plain’ strings passed around, but with magic attached to them,
so that error​::code($@​) or error​::id($@​) will be able to tell us where it
originated.

That idea was shot down immediately as making strings ‘more complex’, and
since we have objects for this purpose we might as well use them. (See
above, how the latter will break things.)

However, I think the magic implementation could just be an implementation
detail.

I have long wanted diagnostics.pm to have a ‘splain’ function that will
be able to describe a message for me, instead of requiring me to use warn
hooks or pipe error messages to the ‘splain’ program.

The thing is, we already have such functionality available; we just need
to expose it better.

Put two ideas together and we come up with this​: The functions we provide
for identifying a message (error​::code or error​::id, whichever you prefer)
could work like diagnostics.pm (i.e., matching the text), but the
messages generated by perl could have magic attached to them storing the ID
for efficiency. To the Perl programmer, the difference between "Bad hash
at foo line 1.\n" from a string literal or input and the same string from
$@​ can be transparent. error​::code is just more efficient on the latter.

All error codes should ideally be alphanumeric, to keep them memorable. I
would hate having to write ‘no warnings "97"’ to disable a specific
warning. Since we already have warning categories, let’s do
"category​::shortid". I’m not sure whether we should categorize errors.

Perhaps we should also provide a constructor to allow users to create
error objects via error->new(message => xxxx, id => xxx, line => xxx, file,
=> xxx). error​::code() would take objects and strings.

I was thinking of a simpler approach. Why not just have an environment
variable, which when true prepends an error code, say in square brackets to
the warnings, and as a side effect enabled localized translations of the
errors?

So where we now have something like​:

$ perl -wle'my $x; print 0+$x'
Use of uninitialized value $x in addition (+) at -e line 1.
0

We would instead have something like

$ perl -wle'my $x; print 0+$x'
[PERL-W001] Use of uninitialized value $x in addition (+) at -e line 1.
0

The [PERL-W001] would be constant irregardless of localization. A simple
regex would then suffice to extract error codes and etc.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @cpansprout

On Tue Sep 16 17​:18​:46 2014, demerphq wrote​:

I was thinking of a simpler approach. Why not just have an environment
variable, which when true prepends an error code, say in square
brackets to
the warnings, and as a side effect enabled localized translations of
the
errors?

So where we now have something like​:

$ perl -wle'my $x; print 0+$x'
Use of uninitialized value $x in addition (+) at -e line 1.
0

We would instead have something like

$ perl -wle'my $x; print 0+$x'
[PERL-W001] Use of uninitialized value $x in addition (+) at -e line
1.
0

The [PERL-W001] would be constant irregardless of localization. A
simple
regex would then suffice to extract error codes and etc.

Action at a distance​: Module​::Runtime (exempli gratia) does $@​ !~ /\ACan't locate.../, which will break if someone has set the environment variable.

Let’s not add $ENV{PERL_ERROR_CODES} the list of things that modules have to localise ($! $@​ $\ $_ etc.).

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @demerphq

On 17 September 2014 03​:11, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 17​:18​:46 2014, demerphq wrote​:

I was thinking of a simpler approach. Why not just have an environment
variable, which when true prepends an error code, say in square
brackets to
the warnings, and as a side effect enabled localized translations of
the
errors?

So where we now have something like​:

$ perl -wle'my $x; print 0+$x'
Use of uninitialized value $x in addition (+) at -e line 1.
0

We would instead have something like

$ perl -wle'my $x; print 0+$x'
[PERL-W001] Use of uninitialized value $x in addition (+) at -e line
1.
0

The [PERL-W001] would be constant irregardless of localization. A
simple
regex would then suffice to extract error codes and etc.

Action at a distance​: Module​::Runtime (exempli gratia) does $@​ !~
/\ACan't locate.../, which will break if someone has set the environment
variable.

Let’s not add $ENV{PERL_ERROR_CODES} the list of things that modules have
to localise ($! $@​ $\ $_ etc.).

Ok, so then make is a lexically scoped pragma. The point is, it doesnt
require any funky error objects or extra functions or anything like that.
Just good old regexes. (Which as you know I am partial to :-)

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @cpansprout

On Tue Sep 16 18​:19​:42 2014, demerphq wrote​:

On 17 September 2014 03​:11, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 17​:18​:46 2014, demerphq wrote​:

I was thinking of a simpler approach. Why not just have an environment
variable, which when true prepends an error code, say in square
brackets to
the warnings, and as a side effect enabled localized translations of
the
errors?

So where we now have something like​:

$ perl -wle'my $x; print 0+$x'
Use of uninitialized value $x in addition (+) at -e line 1.
0

We would instead have something like

$ perl -wle'my $x; print 0+$x'
[PERL-W001] Use of uninitialized value $x in addition (+) at -e line
1.
0

The [PERL-W001] would be constant irregardless of localization. A
simple
regex would then suffice to extract error codes and etc.

Action at a distance​: Module​::Runtime (exempli gratia) does $@​ !~
/\ACan't locate.../, which will break if someone has set the environment
variable.

Let’s not add $ENV{PERL_ERROR_CODES} the list of things that modules have
to localise ($! $@​ $\ $_ etc.).

Ok, so then make is a lexically scoped pragma. The point is, it doesnt
require any funky error objects or extra functions or anything like that.
Just good old regexes. (Which as you know I am partial to :-)

What about code like LWP that catches errors and turns them into response objects? You can add your own protocols to LWP by providing your own LWP​::Protocol classes. If your classes throw errors and some of them have the pragma turned on, then your response objects are no longer formatted consistently. (Oh no, there’s the C word again.) While that could be construed as LWP’s problem, I think this example demonstrates how errors naturally transcend lexical scopes.

And I *do* like solutions involving regular expressions. That is exactly what I was suggesting when I mentioned giving error​::id/code diagnostic.pm’s capabilities. What do you think diagnostic.pm uses? :-)

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @demerphq

On 17 September 2014 05​:35, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 18​:19​:42 2014, demerphq wrote​:

On 17 September 2014 03​:11, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 17​:18​:46 2014, demerphq wrote​:

I was thinking of a simpler approach. Why not just have an
environment
variable, which when true prepends an error code, say in square
brackets to
the warnings, and as a side effect enabled localized translations of
the
errors?

So where we now have something like​:

$ perl -wle'my $x; print 0+$x'
Use of uninitialized value $x in addition (+) at -e line 1.
0

We would instead have something like

$ perl -wle'my $x; print 0+$x'
[PERL-W001] Use of uninitialized value $x in addition (+) at -e line
1.
0

The [PERL-W001] would be constant irregardless of localization. A
simple
regex would then suffice to extract error codes and etc.

Action at a distance​: Module​::Runtime (exempli gratia) does $@​ !~
/\ACan't locate.../, which will break if someone has set the
environment
variable.

Let’s not add $ENV{PERL_ERROR_CODES} the list of things that modules
have
to localise ($! $@​ $\ $_ etc.).

Ok, so then make is a lexically scoped pragma. The point is, it doesnt
require any funky error objects or extra functions or anything like that.
Just good old regexes. (Which as you know I am partial to :-)

What about code like LWP that catches errors and turns them into response
objects?

Unless LWP enabled the pragma it wouldn't matter would it?

You can add your own protocols to LWP by providing your own LWP​::Protocol
classes. If your classes throw errors and some of them have the pragma
turned on, then your response objects are no longer formatted
consistently. (Oh no, there’s the C word again.)

That sounds like a "so dont do that" problem.

While that could be construed as LWP’s problem, I think this example
demonstrates how errors naturally transcend lexical scopes.

Im not sure I see the problem in the same way you do.

And I *do* like solutions involving regular expressions. That is exactly
what I was suggesting when I mentioned giving error​::id/code diagnostic.pm’s
capabilities. What do you think diagnostic.pm uses? :-)

I dunno if I can say why cogently, but that doesnt sound like the right
approach to me.

We want it so that when someone runs a perl script and they get an error or
warning that they see an error in their own language, which includes an
identifier that allows people like us to know what the error was without
having to understand something like tamil.

If the only way you get such a thing is by using special function it seems
to me we are going to have a solution that does not fit the problem we want
to solve. (Or at least the problem I want to solve.)

I guess this one of those things that if we really want to do it right we
are just going to have to deal with modules that include code that tries to
parse error messages. My guess is that it is not /that/ common a thing to
do, although relatively common anyway.

BTW, I am pretty sure at least one or two custom ports of Perl already do
more or less what I describe anyway.

So either we do something like you describe, which IMO is only marginally
better than what we do now, or we risk a bunch of one-time back compat
issues. On the other hand it will be a *one* time change. Once we do it the
people that are parsing internal errors will have a reliable identifier to
use.

Yves

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @cpansprout

On Tue Sep 16 20​:54​:41 2014, demerphq wrote​:

On 17 September 2014 05​:35, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 18​:19​:42 2014, demerphq wrote​:

On 17 September 2014 03​:11, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 17​:18​:46 2014, demerphq wrote​:

I was thinking of a simpler approach. Why not just have an
environment
variable, which when true prepends an error code, say in square
brackets to
the warnings, and as a side effect enabled localized
translations of
the
errors?

So where we now have something like​:

$ perl -wle'my $x; print 0+$x'
Use of uninitialized value $x in addition (+) at -e line 1.
0

We would instead have something like

$ perl -wle'my $x; print 0+$x'
[PERL-W001] Use of uninitialized value $x in addition (+) at -e
line
1.
0

The [PERL-W001] would be constant irregardless of localization.
A
simple
regex would then suffice to extract error codes and etc.

Action at a distance​: Module​::Runtime (exempli gratia) does $@​
!~
/\ACan't locate.../, which will break if someone has set the
environment
variable.

Let’s not add $ENV{PERL_ERROR_CODES} the list of things that
modules
have
to localise ($! $@​ $\ $_ etc.).

Ok, so then make is a lexically scoped pragma. The point is, it
doesnt
require any funky error objects or extra functions or anything like
that.
Just good old regexes. (Which as you know I am partial to :-)

What about code like LWP that catches errors and turns them into
response
objects?

Unless LWP enabled the pragma it wouldn't matter would it?

Hmmm, do you mean adding the error code based on the eval{} site, rather than the die site? I hadn’t thought of that till now.

You can add your own protocols to LWP by providing your own
LWP​::Protocol
classes. If your classes throw errors and some of them have the
pragma
turned on, then your response objects are no longer formatted
consistently. (Oh no, there’s the C word again.)

That sounds like a "so dont do that" problem.

But LWP​::Protocol classes may be written by different authors. You’re saying I should stick to old-style error messages just because my module is used by LWP when available?

(This question only applies if we base the pragma on where the error is thrown.)

While that could be construed as LWP’s problem, I think this example
demonstrates how errors naturally transcend lexical scopes.

Im not sure I see the problem in the same way you do.

Apparently not. :-)

I have several times had to right code that recognizes Perl error messages and re-throws some of them, and this among 30 modules or so calling each other. If some code expects error codes and some does not, that complicates things.

And I *do* like solutions involving regular expressions. That is
exactly
what I was suggesting when I mentioned giving error​::id/code
diagnostic.pm’s
capabilities. What do you think diagnostic.pm uses? :-)

I dunno if I can say why cogently, but that doesnt sound like the
right
approach to me.

I only meant that as a fallback, if the magic attached to the error is gone.

We want it so that when someone runs a perl script and they get an
error or
warning that they see an error in their own language, which includes
an
identifier that allows people like us to know what the error was
without
having to understand something like tamil.

I had not considered that use case. The gradual change in wording that happens with each release was the only thing I had in mind.

If the only way you get such a thing is by using special function it
seems
to me we are going to have a solution that does not fit the problem we
want
to solve. (Or at least the problem I want to solve.)

I guess this one of those things that if we really want to do it right
we
are just going to have to deal with modules that include code that
tries to
parse error messages. My guess is that it is not /that/ common a thing
to
do, although relatively common anyway.

BTW, I am pretty sure at least one or two custom ports of Perl already
do
more or less what I describe anyway.

So either we do something like you describe, which IMO is only
marginally
better than what we do now, or we risk a bunch of one-time back compat
issues. On the other hand it will be a *one* time change. Once we do
it the
people that are parsing internal errors will have a reliable
identifier to
use.

In that case what you suggest makes sense. But I think we need to put the error code at the end of the message, rather than at the beginning, if we do it universally.

Just look at <http​://grep.cpan.me/?q=\%24%40+%3D~+%2F\^>​:

$@​ =~ /^Can't locate/
$@​ =~ /^Insecure \$ENV{TERM}/
$@​ =~ /^Insecure directory in \$ENV{TERM}/
$@​ =~ /^Too many arguments/
$@​ =~ /^Can't locate object method "ProxyRemoteAddr"/
$@​ =~ /^Can't locate .*\.pm in \@​INC/

If we do it based on the eval site, then I suppose the error code could go at the beginning, but the thing I mention above about re-throwing errors (does my caller want the error code?) still applies then.

Since warnings should have these as well, and we already have lowercase alphabetic identifiers for some warnings (though with :​: as well​: experimental​::postderef), I suggest we use lowercase names, rather than PERL-W001. That way they will be recognizable without having to look up the number​:

-e வரி 1 பக்கம் வழிதல். [format​::overflow]

Forgive the clunky machine translation.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @cpansprout

On Tue Sep 16 22​:33​:32 2014, I wrote​:

I have several times had to right code

Gah! How did I manage that? I’m not that illiterate! It should be ‘write’, of course.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @demerphq

On 17 September 2014 07​:42, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 22​:33​:32 2014, I wrote​:

I have several times had to right code

Gah! How did I manage that? I’m not that illiterate! It should be ‘write’,
of course.

I got you write the first place. :-)

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From PeterCMartini@GMail.com

Are error/warning objects out of the discussion because of backcompat
concerns, or preference?

I much prefer objects, because we can get a sane tree of them - which
we already have, for warnings, and to a much lesser extent for errors.

What if we create a new (C-level) variable, PL_errsv, with PL_errgv
just being a tied scalar which stringifies PL_errsv if its ever called
- and have the optimizer replace gvsv(*@​) calls with a new opcode / XS
function that retrieves PL_errsv if use v5.22 or use feature
'error_codes' is in play? That would lexically control whether the
error (or warning) appears to be a string or an object based on
actually trying to read it, even though internally we'd always
generate an object and can carry around a fairly normal Perl
structure.

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @cpansprout

On Tue Sep 16 22​:49​:16 2014, pcm wrote​:

Are error/warning objects out of the discussion because of backcompat
concerns, or preference?

Probably a bit of both, but mostly the former.

I much prefer objects, because we can get a sane tree of them - which
we already have, for warnings, and to a much lesser extent for errors.

What if we create a new (C-level) variable, PL_errsv, with PL_errgv
just being a tied scalar

Assuming you mean GvSV(PL_errgv), you are not taking local *@​ into account. I’ve had to do that in some of my code to work around perl bugs.

which stringifies PL_errsv if its ever called
- and have the optimizer replace gvsv(*@​) calls with a new opcode / XS
function that retrieves PL_errsv if use v5.22 or use feature
'error_codes' is in play?

The tied variable itself could choose whether to return a reference

That would lexically control whether the
error (or warning) appears to be a string or an object based on
actually trying to read it, even though internally we'd always
generate an object and can carry around a fairly normal Perl
structure.

Nice idea, but it needs simplification. :-)

How about a new variable? ${^ERROR_OBJ} contains the object. $@​ contains the string.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @b2gills

On Wed, Sep 17, 2014 at 12​:59 AM, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Tue Sep 16 22​:49​:16 2014, pcm wrote​:

Are error/warning objects out of the discussion because of backcompat
concerns, or preference?

Probably a bit of both, but mostly the former.

I much prefer objects, because we can get a sane tree of them - which
we already have, for warnings, and to a much lesser extent for errors.

What if we create a new (C-level) variable, PL_errsv, with PL_errgv
just being a tied scalar

Assuming you mean GvSV(PL_errgv), you are not taking local *@​ into account. I’ve had to do that in some of my code to work around perl bugs.

which stringifies PL_errsv if its ever called
- and have the optimizer replace gvsv(*@​) calls with a new opcode / XS
function that retrieves PL_errsv if use v5.22 or use feature
'error_codes' is in play?

The tied variable itself could choose whether to return a reference

That would lexically control whether the
error (or warning) appears to be a string or an object based on
actually trying to read it, even though internally we'd always
generate an object and can carry around a fairly normal Perl
structure.

Nice idea, but it needs simplification. :-)

How about a new variable? ${^ERROR_OBJ} contains the object. $@​ contains the string.

I think it should be a single perl data structure so that it gets
passed around by old code that thinks its a string.

So just have it be a tied object that acts like a string.
( could be a new lightweight object just for this purpose )

I don't think it would be too annoying that you have to
call tied on it every time you want more information.

Perhaps we could add a CATCH block similar to Perl6
that calls tied on it for us if it gets a tied object.
The CATCH block would have to be able to deal with plain strings,
Perl tied error objects, user error objects, and arbitrary data structures.

If you rethrow a Perl error object it should get tied like it was
to start with.

Just a quick <10min thought.

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @Abigail

I'm not to fond of the "let's change the behaviour, and have it controlled
by a pragma/environment variable/something else".

Why not something like​:

  * We leave $@​ as is.
  * If $@​ is set, we also set ${^ERROR_CODE}, which will contain a
  the error code.
  * If a warning is thrown, we also set ${^WARNING_CODE}, which will
  contain an warning code (that way, a program can inspect its warnings).
  * We'll also garantee the error/warning codes will not
  change in the future (but new ones may be added).

That way, any existing code remains working. And there's no action at a
distance -- there's always a way to get the unique error code, and you
don't have to turn a switch somewhere away from the code dealing with
the error.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @rjbs

* Abigail <abigail@​abigail.be> [2014-09-17T11​:51​:05]

I'm not to fond of the "let's change the behaviour, and have it controlled
by a pragma/environment variable/something else".

...and I think that in this case, it's going to be confusing. Errors happily
leap over lexical boundaries, and we expect to be able to compose together
software units with errors moving between them. That is​: exceptions are not
lexical in effect, so changing them based on their lexical point of origin is a
half measure, at beast.

Why not something like​:

* We leave $@​ as is.
* If $@​ is set, we also set ${^ERROR_CODE}, which will contain a
the error code.

Once we are doing this, why not ${^ERROR_OBJ}? It need only provide, for now,
say, ->as_string and ->ident. Or something like that.

At any rate, I think it's a promising idea.

--
rjbs

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @ap

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2014-09-17 07​:35]​:

Since warnings should have these as well, and we already have
lowercase alphabetic identifiers for some warnings (though with :​: as
well​: experimental​::postderef), I suggest we use lowercase names,
rather than PERL-W001. That way they will be recognizable without
having to look up the number​:

-e வரி 1 பக்கம் வழிதல். [format​::overflow]

I like this.

I particularly like the idea of this being the same identifier you would
pass to “no warnings” to silence that particular warning. That is good
language usability.

The »PERL-W« part also serves a usability role in the other proposal,
though, in making the error easily Google-able. I suggest that some such
prefix be part of this proposal as well. “[p5w format​::overflow]” (with
a corresponding “p5e” for errors)? It’s somewhat cryptic, but it’ll work
for search engines, as it is the full phrase [p5w format overflow] that
needs to be sufficiently unique. Less cryptic prefixes rapidly make for
a mouthful. “[p5warn format​::overflow]”? Hmm.

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Sep 17, 2014

From @jhi

Ok, so then make is a lexically scoped pragma. The point is, it doesnt
require any funky error objects or extra functions or anything like
that. Just good old regexes. (Which as you know I am partial to :-)

If we have more 'structure' in the errors (class, severity, message,
file, line, date, shoesize, ...), let's NOT try squishing them into
a linear string, please. Regexps are cool and everything, but they are
a fragile introspection tool for structured data.

@p5pRT
Copy link
Author

p5pRT commented Sep 18, 2014

From @cpansprout

On Wed Sep 17 08​:57​:18 2014, perl.p5p@​rjbs.manxome.org wrote​:

* Abigail <abigail@​abigail.be> [2014-09-17T11​:51​:05]

I'm not to fond of the "let's change the behaviour, and have it
controlled
by a pragma/environment variable/something else".

...and I think that in this case, it's going to be confusing. Errors
happily
leap over lexical boundaries, and we expect to be able to compose
together
software units with errors moving between them. That is​: exceptions
are not
lexical in effect, so changing them based on their lexical point of
origin is a
half measure, at beast.

Why not something like​:

* We leave $@​ as is.
* If $@​ is set, we also set ${^ERROR_CODE}, which will contain a
the error code.

Once we are doing this, why not ${^ERROR_OBJ}? It need only provide,
for now,
say, ->as_string and ->ident. Or something like that.

At any rate, I think it's a promising idea.

It still poses the problem of re-throwing errors.

So perhaps die($@​) should imply die(error-&gt;new($@​)) if $@​ is a string. And that brings us full circle​: error-&gt;new needs to recognize the error ID in $@​, so attaching it via magic would make this faster, but we would still need to be able to parse the string.

Yves’ suggestion of adding the ID to the stringification helps significantly here.

Also, what if someone writes die(${^ERROR_OBJ})? Should any object of class 'error' (as opposed to something from a CPAN error module) be stringified when fed to $@​, the original object being retained in ${^ERROR_OBJ}?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2014

From @rgarcia

On 17 September 2014 17​:51, Abigail <abigail@​abigail.be> wrote​:

I'm not to fond of the "let's change the behaviour, and have it controlled
by a pragma/environment variable/something else".

Why not something like​:

* We leave $@​ as is.
* If $@​ is set, we also set ${^ERROR_CODE}, which will contain a
the error code.
* If a warning is thrown, we also set ${^WARNING_CODE}, which will
contain an warning code (that way, a program can inspect its warnings).
* We'll also garantee the error/warning codes will not
change in the future (but new ones may be added).

That way, any existing code remains working. And there's no action at a
distance -- there's always a way to get the unique error code, and you
don't have to turn a switch somewhere away from the code dealing with
the error.

I was thinking about this thread and I wonder what codes should be assigned
to registered lexical warnings ? (by warnings​::register) Surely that's
a limitation
of using numbers ?

Also, if someone turns on fatalisation of a warning, should the code be reported
as an error code or a warning code ? (Personally I would be in favor
of chainsawing
out fatal warnings, but I don't see that happening, so we need to cope with them
in some way)

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2014

From @lizmat

On 23 Sep 2014, at 10​:01, Rafael Garcia-Suarez <rgs@​consttype.org> wrote​:

On 17 September 2014 17​:51, Abigail <abigail@​abigail.be> wrote​:

I'm not to fond of the "let's change the behaviour, and have it controlled
by a pragma/environment variable/something else".

Why not something like​:

* We leave $@​ as is.
* If $@​ is set, we also set ${^ERROR_CODE}, which will contain a
the error code.
* If a warning is thrown, we also set ${^WARNING_CODE}, which will
contain an warning code (that way, a program can inspect its warnings).
* We'll also garantee the error/warning codes will not
change in the future (but new ones may be added).

That way, any existing code remains working. And there's no action at a
distance -- there's always a way to get the unique error code, and you
don't have to turn a switch somewhere away from the code dealing with
the error.

I was thinking about this thread and I wonder what codes should be assigned
to registered lexical warnings ? (by warnings​::register) Surely that's
a limitation
of using numbers ?

Also, if someone turns on fatalisation of a warning, should the code be reported
as an error code or a warning code ? (Personally I would be in favor
of chainsawing
out fatal warnings, but I don't see that happening, so we need to cope with them
in some way)

Far being it for me to suggest an approach from Perl 6. But maybe you just need to define a class per exception, and define its API there and then, instead of using numbers? Such classes typically start with X​:: in Perl 6.

Then translation would just mean overriding these classes with another language’s version, as long as they have the same API, that shouldn’t be a problem?

Liz

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2014

From @Abigail

On Tue, Sep 23, 2014 at 10​:01​:34AM +0200, Rafael Garcia-Suarez wrote​:

On 17 September 2014 17​:51, Abigail <abigail@​abigail.be> wrote​:

I'm not to fond of the "let's change the behaviour, and have it controlled
by a pragma/environment variable/something else".

Why not something like​:

* We leave $@​ as is.
* If $@​ is set, we also set ${^ERROR_CODE}, which will contain a
the error code.
* If a warning is thrown, we also set ${^WARNING_CODE}, which will
contain an warning code (that way, a program can inspect its warnings).
* We'll also garantee the error/warning codes will not
change in the future (but new ones may be added).

That way, any existing code remains working. And there's no action at a
distance -- there's always a way to get the unique error code, and you
don't have to turn a switch somewhere away from the code dealing with
the error.

I was thinking about this thread and I wonder what codes should be assigned
to registered lexical warnings ? (by warnings​::register) Surely that's
a limitation of using numbers ?

But all bets are off with user generated warnings anyway, whether they
use warnings​::register or not. The point of this exercise is to make
sure we have an easy way to determine a generated warning/error, which
will stay fixed over time. But no matter what we decide to use for perl
itself, I don't see a way to enforce this on user code.

Perhaps we can recommend that each package keeps its own list of numbers,
and we automatically prepend the package name from which a user generated
warning is issued. But I don't see many people writing​:

  if (${^WARNING_OBJ} -> warning_code eq "Some​::Long​::Package​::Name​::Several​::Levels​::Deep​::127") {
  do_something;
  }
  elsif (${^WARNING_OBJ} -> warning_code eq "Some​::Long​::Package​::Name​::Several​::Levels​::Deep​::73") {
  do_something_else;
  }
  ...

Also, if someone turns on fatalisation of a warning, should the code be
reported as an error code or a warning code? (Personally I would be in favor
of chainsawing out fatal warnings, but I don't see that happening, so we
need to cope with them in some way)

I'm included to say "error code", but if we go for numbers, I strongly
suggest we draw error and warning codes from the same pool. That way, if
warning with code X is fatalized, it's fatalized as an error with code X.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2014

From @cpansprout

On Tue Sep 23 01​:02​:16 2014, rgs@​consttype.org wrote​:

I was thinking about this thread and I wonder what codes should be
assigned
to registered lexical warnings ? (by warnings​::register) Surely that's
a limitation
of using numbers ?

I have been opposed to numbers from the beginning, because we already have warning categories, and those should be part of the warning ID.

Modules that register warnings can just do MyPackage​::toolumpy or whatever for the warning ID.

Also, if someone turns on fatalisation of a warning, should the code
be reported
as an error code or a warning code ?

There would be no distinction between the two.

(Personally I would be in favor
of chainsawing
out fatal warnings, but I don't see that happening, so we need to cope
with them
in some way)

What do you have against fatal warnings? Is it the same thing I have against them, that you are shooting yourself in the foot?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2014

From @demerphq

On 23 September 2014 17​:33, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 23 01​:02​:16 2014, rgs@​consttype.org wrote​:

I was thinking about this thread and I wonder what codes should be
assigned
to registered lexical warnings ? (by warnings​::register) Surely that's
a limitation
of using numbers ?

I have been opposed to numbers from the beginning, because we already have
warning categories, and those should be part of the warning ID.

Modules that register warnings can just do MyPackage​::toolumpy or whatever
for the warning ID.

The reason I favour numeric ids is that they are truly transligual.

Yves
--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Sep 25, 2014

From @cpansprout

On Tue Sep 23 09​:29​:51 2014, demerphq wrote​:

On 23 September 2014 17​:33, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Tue Sep 23 01​:02​:16 2014, rgs@​consttype.org wrote​:

I was thinking about this thread and I wonder what codes should be
assigned
to registered lexical warnings ? (by warnings​::register) Surely that's
a limitation
of using numbers ?

I have been opposed to numbers from the beginning, because we already have
warning categories, and those should be part of the warning ID.

Modules that register warnings can just do MyPackage​::toolumpy or whatever
for the warning ID.

The reason I favour numeric ids is that they are truly transligual.

But they are not particularly memorable. Put them in Sepedi or Japanese if you have to. I won’t complain, as long as they are more memorable than numbers.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 25, 2014

From @karenetheridge

On Wed, Sep 24, 2014 at 10​:07​:39PM -0700, Father Chrysostomos via RT wrote​:

The reason I favour numeric ids is that they are truly transligual.

But they are not particularly memorable. Put them in Sepedi or Japanese if you have to. I won’t complain, as long as they are more memorable than numbers.

Why not numbers *and* names, where they are considered equivalent to each
other? e.g. the possible values of $! are all integers, but they also have
code words of ~8 letters, as well as as a longer stringified form.

@p5pRT
Copy link
Author

p5pRT commented Sep 25, 2014

From @demerphq

On 25 September 2014 07​:46, Karen Etheridge <perl@​froods.org> wrote​:

On Wed, Sep 24, 2014 at 10​:07​:39PM -0700, Father Chrysostomos via RT wrote​:

The reason I favour numeric ids is that they are truly transligual.

But they are not particularly memorable. Put them in Sepedi or Japanese
if you have to. I won’t complain, as long as they are more memorable than
numbers.

Why not numbers *and* names, where they are considered equivalent to each
other? e.g. the possible values of $! are all integers, but they also have
code words of ~8 letters, as well as as a longer stringified form.

Yes I agree. An error should have a number, a symbolic code, and a
localized string associated with it.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@xenu xenu removed the Severity Low label Dec 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants