On Mon, 02 Jan 2017 16:35:46 -0800, comdog wrote: > Trying to output a character unrepresentable in the specified > encoding throws an X::AdHoc error. I think that should be X::IO, > and maybe there's enough issues here that an X::IO::Exception may > be interesting enough. > > my $file = 'encoding_test.txt'; > my $path = $*SPEC.catfile( $*SPEC.tmpdir, $file ); > > spurt $path, 'İstanbul', enc => 'iso-8859-1'; > > CATCH { > put "Caught {.^name}: {.message}"; > } > > Here'e the error: > > Caught X::AdHoc: Error encoding Latin-1 string: could not encode > codepoint 304 > Error encoding Latin-1 string: could not encode codepoint 304
FWIW, not all encoding has to do with IO, and there is an X::Encoding namespace already... it should probably go there. This particular error occurs in the VM (at least on rakudo-m). Currently exception passing from MoarVM is limited to a single type of exception. Supposedly there's to be a mechanism to register an alternate VMException-compatible HLL object but I don't see that from reading the code... the one in boot_types seems to be used everywhere. I'd say it's better to wait for that Moar work, or a decision not to do that, than to start tearing into the text of VMException contents and trying to figure out what other exception to wrap it in other than an X::AdHoc. In certain cases we can immediately catch exceptions from the VM in wrapper functions around an NQP call. If the VM would let us build a different exception in that handler and attach it to the HLL-registered exception and rethrow it, then the exception handler could detect that and the next time it emerges, maybe some slight of hand could make that new exception take the place of the original while keeping backtraces intact. I only mention that because it is a way we could keep the code that examines VM exceptions and maps them to HLL exception types local to the relevant code in both the HLL and in MoarVM, so we don't have to have big switch statements and consider some sort of centralized registry in MoarVM to keep two unrelated VM exceptions from clashing and becoming indistinguishable to the HLL. I played a bit with that but it looks like trying to change the BOOTException payload doesn't happen, though you can change its message: perl6 -e 'use nqp; sub f { "dh°".encode("ascii"); CATCH { when X::AdHoc { my \xp = nqp::getattr($_, Exception, "\$\!ex"); nqp::setmessage(xp, nqp::decont("foo")); nqp::setpayload(xp, nqp::decont(X::NYI.new())); $_.rethrow } } }; f(); CATCH { ":: {$_.perl} { my \xp = nqp::getattr($_, Exception, "\$\!ex"); my \xpp = nqp::getpayload(xp); xpp.^name } ::".say }' :: X::AdHoc.new(payload => "Error encoding ASCII string: could not encode codepoint 176") X::AdHoc :: foo in sub f at -e line 1 in block <unit> at -e line 1 ...that would have required some further alterations to EXCEPTION to detect the changed payload, even if setting the payload had worked. Or maybe it did work and EXCEPTION undid it...