[Grok-dev] Re: three ways to do error messages
faassen at startifact.com
Mon May 12 15:05:55 EDT 2008
Brandon Craig Rhodes wrote:
> I started a branch to start making Grok error messages more friendly
> and less traceback-crazed, and realized that there are at least three
> approaches we could take. Maybe more. I'll outline them; please
> weigh in on which way we should take, I'm eager to get started:
> 1. Where we today raise GrokError, we could call a function that
> prints the message, and then does something like a sys.exit(1) to
> avoid a traceback.
Exceptions are good. Building our own mechanism to replace exceptions
isn't good, and this would require a lot of changes everywhere. Instead
handle this where we *catch* GrokErrors.
> 2. We could raise an error that martian recognizes and then martian
> could take responsibility for printing it and doing the
> sys.exit(1). Since all of the GrokErrors I've seen so far are
> ones for which a traceback is useless - and, after all, if the
> error occurs during grokking, then by definition hasn't the code
> that caused the error already been run? - maybe GrokError could
> become the one that doesn't bother with an exception, and we could
> invent a GrokErrorWithException or something to cover any corner
> cases we found where one is needed.
I think it's not the responsibility of Martian right now to provide nice
error messages. For two reasons:
* we don't know what we're doing yet. Once we do know it we might move
stuff into Martian, or some special grokcore.configuration package.
* Zope's configuration machinery is in play, which Martian knows nothing
about. This means we have to do this in at least grokcore.component
> 3. Maybe the grokkers should all be run, catching GrokErrors along
> the way, and then they should all print at once, so if you've
> forgotten three templates you get told all at the same time
> instead of fixing one problem, re-running Grok, etc? I would be
> against this if Grok errors turn out to be the sort that cascade,
> creating the horrible "cc" situation where you get buried with
> consequences of some single, initial error that's way way up at
> the top of the output. But my impression so far is that they're
> pretty atomic - that they don't tend to "cause" each other.
I agree they look pretty atomic. Still I'd like to reduce the ambition
level: let's, for now, fail on the first grok error and show nice output
there. Later we worry about collecting errors. Note that Python doesn't
collect its SyntaxErrors or ImportErrors either; you just restart your
program and you get the next one. I think this behavior is all right, as
at least it avoids a lot of spamming.
Note that GrokError isn't the only thing that's in play here. Import
errors or syntax errors tend to get hidden in quite horrible looking
tracebacks too now, due to Zope's configuration machinery.
> Plus, there's the whole other issue - which might need work on Zope
> itself - that SyntaxErrors raised during testing never show me the
> dratted line of code that I've messed up, but instead just show me the
> line number and a completely useless traceback into some horrible ZCML
> code or something. Should we try fixing this too? I'm not as
> concerned with the testing story as with general development at the
> moment, though.
Yes, we should try fixing this too. It's not just the testing story, the
same problem, I think, should occur for any file that is only touched
through Grokking. import errors are the same problem.
Anyway, I think you should look into handling configuration errors (and
pulling the grok errors out). Let the first goal be getting rid of the
horrible configuration error "shell" that all errors get embedded in now
Possibly the right place to start interfering for GrokError is in
somewhere in grokcore.component.zcml, for instance in the implementation
of grokDirective. Note that this module might one day be the base of
It'll be interesting to try to find a better place to start interfering
in the horrible ZCML wrapper. I think we should look in
zope.configuration, see what we can do there. Perhaps we can tweak it so
we can use it in a mode where it doesn't wrap everything in its own
machinery, but shows the inner traceback, unless it's a ConflictError or
something (where still we can show a nicer error). Or perhaps we can do
this in our own package, grokcore.configuration.
Sorry to not give you a direct line of attack here. A sys.exit() is only
all right with me if we localize it and still catch exceptions: we catch
an exception normally, then extract our error information from it, and
display it, then doing a sys.exit(). The error information might be a
classic traceback in case of problems in Python code, a ConflictError of
some kind if it's a configuration conflict, or a GrokError (perhaps with
less traceback) if it's a GrokError.
More information about the Grok-dev