Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Exception handling and "trap" vs. TRAPNAL()
- X-seq: zsh-workers 21816
- From: DervishD <zsh@xxxxxxxxxxxx>
- To: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- Subject: Re: Exception handling and "trap" vs. TRAPNAL()
- Date: Mon, 3 Oct 2005 19:59:13 +0200
- Cc: zsh-workers@xxxxxxxxxx
- In-reply-to: <1051003162109.ZM4533@xxxxxxxxxxxxxxxxxxxxxxx>
- Mail-followup-to: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>, zsh-workers@xxxxxxxxxx
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- Organization: DervishD
- References: <20051001153756.GA12183@DervishD> <1051001183818.ZM27904@xxxxxxxxxxxxxxxxxxxxxxx> <20051001202856.GA134@DervishD> <1051002044052.ZM28373@xxxxxxxxxxxxxxxxxxxxxxx> <20051002190940.437F9866F@xxxxxxxxxxxxxxxxxxxxxxxx> <1051002195518.ZM2163@xxxxxxxxxxxxxxxxxxxxxxx> <20051002230027.GA194@DervishD> <1051003013758.ZM3107@xxxxxxxxxxxxxxxxxxxxxxx> <20051003090121.GC278@DervishD> <1051003162109.ZM4533@xxxxxxxxxxxxxxxxxxxxxxx>
Hi Bart :)
* Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> dixit:
> On Oct 3, 11:01am, DervishD wrote:
> } I know, I know, but AFAIK the "always" block works more or less
> } the same as exception handling does in other languages.
> Less, not more. The problem is that in a language with real
> exceptions, the difference between an error and an exception is
> well-defined, and it is usually possible to have errors without
> exceptions and vice-versa. Zsh's "always" block is an error
> handler, not an exception handler, and PWS's functions are
> overloading the meaning of "error".
But always blocks handle errors that would cause the shell to
abort execution. In a certain way, they are exceptions, they're
different from errors (with "error" I mean the usual "non-zero exit
code").
> } > } Propagating "errflag" may break current code only if that code is
> } > } using an inline trap which "returns" a value and that error value is
> } > } ignored on purpose.
> } > That's not quite correct. Remember, an inline trap using the "return"
> } > builtin actually causes the surrounding/calling context to return
> }
> } That's why I was quoting "return": I didn't mean a literal
> } "return" command, but a way of returning a value to the current code.
>
> Yes, but there *isn't* any way of returning a value to the surrounding
> code -- unless you mean something like setting $REPLY. So your basis
> for the statement is a practical impossibility.
I was thinking exactly that, using $REPLY or something similar. I
just wasn't sure if the trap restored all the environment or not.
> } But if you propagate the error, you won't break such code. I
> } mean, even with your patch, this code...
> }
> } trap 'readonly VAR; VAR=0' ZERR
> }
> } print "HERE"
> } false
> } print "HERE AGAIN"
> }
> } ...will print both strings.
>
> In 4.0.6, or with my second potential patch, that prints only "HERE"
> (plus the error message about the readonly assignment). In 4.2.5, it
> prints both strings. In bash2, it also prints both strings. Anything
> that relies on the 4.2.5 or bash2 behavior will break if we go back to
> propagating the error as was done in 4.0.6.
It doesn't seem to be a good idea, then...
> } O:)) As far as I understan, "errflag" just signals the error and
> } propagate it to the current execution environment (for inline traps,
> } I mean), but doesn't make the shell abort :?
> It doesn't make the shell *exit*, but it does stop execution in the
> way that would jump into an "always" block. (If it did not, how
> would it solve your problem?) In the absence of the "always", it
> simply bails out of the current context. The "always" block is a way
> to intercept the "bail out" action, but the bail-out happens whether
> "always" is there or not.
OK, I just was assuming that without the always block the
execution would go on undisturbed, which is false. I don't know why I
got that false impression, because I really know that code like this:
readonly VAR
VAR=
will stop execution. Sorry, my fault.
> } If no patch is applied I can still use TRAPNAL's for throwing
> } exceptions, but I must think a way of doing that with inline traps,
> } which I think it's impossible because the value of TRY_BLOCK_ERROR is
> } reset.
> You're right, it's impossible. You'll have to think about how you
> would write the code if you never had "always" in the first place,
> and write it that way.
The problem is that I would like to use "always" blocks with the
"nonzeroexitcode" kind of errors (that's why I use ZERR, it helps me
to convert the normal errors into errors as defined in a try block
context, a condition which causes the shell to stop execution).
Obviously this doesn't need nor exceptions nor always blocks, a
simple "goto" will suffice because what I want is a way of avoiding
handling similar errors in a per-command basis. I mean, I want to
replace this code:
command1 && {# handle here some possible error probably exiting}
command2 && {# handle here exactly the same error as before}
...
commandn && {# incredible, here we must handle a similar error}
with this one:
trap 'throw commonerror$LINENO' ZERR
{
command1
command2
command3
} always {
# Here we catch and handle the common error
# In the exception name we have the line number,
# just in case we want to fine tune error handling
}
I face this kind of code frequently: some tightly coupled
commands that cause the same kind of errors, or whose failures can be
seen as a single error, and execution *must* stop at that point.
That's the whole point. I maybe am using the wrong shell
construct for solving the problem, and obviously I can always use the
first syntax and handle errors one-by-one (and not, something like
this: { command1 || command 2 || command 3 } && {#handle error here}
won't always work for me), but I find the always block construct much
better for this task. If I cannot use the ZERR trap and I must add an
explicit throw call after each command, it still is far better than
handling the error in place, better even than using a function to
handle the error instead of the throw call, because of rethrowing.
With all the information you've given to me, I think now that
it's not a good idea to patch zsh to alter current behaviour, because
I see that current behaviour makes sense, but nonetheless being able
to cause 'alwaysable' errors from inline traps looks very good to me
O:))
Thanks again for all, Bart.
Raúl Núñez de Arenas Coronado
--
Linux Registered User 88736 | http://www.dervishd.net
http://www.pleyades.net & http://www.gotesdelluna.net
It's my PC and I'll cry if I want to...
Messages sorted by:
Reverse Date,
Date,
Thread,
Author