Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Exception handling and "trap" vs. TRAPNAL()



On Oct 1,  8:10pm, Peter Stephenson wrote:
}
} Bart Schaefer wrote:
} > So the question is:  Why ignore errors that occur in inline traps?
} 
} The answer to (1) is that traps are present as error handlers (of some
} sort and for some debatable value of "error") and to avoid confusing
} matters the error is taken from the code surrounding the trap, not the
} trap itself.

Yes, but the "error" of a non-zero command status is not the same as a
shell-level error (syntax or what have you).

} So the whole behaviour that DervishD is seeing is a side affect of the
} fact that this:
} 
}   TRAPZERR() { throw DEFAULT; }
} 
} finishes by executing a command with non-zero status, the throw

It could be argued that, in the presence of an "always" block, the
function should not be considered to have "finished" at all.  The
shell-level error is supposed to have stopped execution; the implict
"return $?" never happened, the return status of the function is not
defined, and we're in no-man's land.

The trouble, of course, is that shell-level errors are not really
exceptions, an "always" block is not really an exception handler, and
nothing is actually "thrown" by "throw", so none of the assumptions
are valid that Raúl is making based on the names "throw" and "catch".
And the implementation simply can't stop execution and unwind to the
"always" block the way a real exception system would.
 
} You can certainly argue that the "normal effect" of a ZERR trap is not
} to cause an error, and it's certainly possible to argue that yet more
} hacked-up special cases and additional bug-prone complexity in the trap
} code are warranted.

Well, that's just it.  An even stronger argument than the no-man's land
proposition, is that errflag should *not* be propagated out of a ZERR
trap.  This would not accomplish what Raúl wants, because it would mean
that *neither* TRAPZERR nor "trap ... ZERR" would be capable of "raising
an exception" -- in effect we'd be removing a special-case, not adding
one.

    } else if (trapreturn >= 0 && !isfunc) {
	/*
	 * Context was an inline trap.  If an explicit return value
	 * was used, we need to set `lastval'.  Otherwise we use the
	 * value restored by execrestore.  In this case, all return
	 * values indicate an explicit return from the current function,
	 * so always handle specially.  trapreturn is always restored by
	 * execrestore.
	 */
	trapret = trapreturn + 1;
    } else if (errflag)
	trapret = 1;

I'm not sure, though, that there isn't some other kind of real signal
that depends on that snippet.

} However, I'm still not convinced this is going anywhere I want to go.

The behavior should be consistent, is all.



Messages sorted by: Reverse Date, Date, Thread, Author