Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2007-10-19 05:19:27


One of the things that Python port cannot directly
grab from Jam codebase is error reporting. Among other
things, because Jam does not have exceptions, and also
because Jam does not have Python stack frames.

I've come to the following list of rules for error handling
in Python code, and would appreciate comments, both from
user perspective and from developer perspective.

1. For each error, we clearly will be able to produce
a raw stacktrace, but it's not very useful. Therefore,
we need some 'user-context' mode of error reporting, where
user is told what high-level actions were performed when
the error happened. For example:

        error: invalid feature 'non-existent'
        - when computing build properties for target 'foo'
        - when build project in '.'

To implement this we need:

  - Maintain those user-contexts
  - Arrange for user-context to be printed or recorded when
  error happens
  - Do something about 'stray' exceptions through in
  Python code, like caused by bugs

2. We should have a module errors with two functions:
'push-context' and 'pop-context'. The first takes a
string description of what we're doing now. Every function
that does something interesting from the user's point of
view should be written like:

        try:
                errors.push_context("Doing something")
                # do something
        finally:
                errors.pop_context()

The try/finally is needed so that if stray exception is thrown,
the pushed used context does not stay pushed forever.

3. Whenever we run into error condition that can be explained in
user terms, we'll use errors.error(). That function will
create new exception type, record current user context into
it, and raise that exception.

4. Python exception should never be allowed to escape back to jam.
Every function called from bjam should try/catch and print
the exception.

5. Every function called from bjam will get bjam stack trace
and add it to user context. So, if error happens user will
see what line from Jamfile caused it.

6. It's possible that we either detect error at too low
level to provide any explanation, or the error is detected
by Python interpreter. In which case, an ordinary exception
will be thrown. To still provide some context, we should
use try/catch at various strategic places, catch such stray
exceptions, and throw new exception, that holds current user
context and the original exception. So, if we try to say
interate over None somewhere deep, we'll get an error message
like this:

        internal-error: Itetarion over non-sequence
        - when building target 'foo'

        Use --backtrace to see Python backtrace

Note that this output is not very useful to debug anything.
It's primarily meant to avoid completely freaking out users
who are not accustomed to Python stacktraces. This way, they'll
at least have the time to open Python docs before getting
real Python stracktrace.

7. When printing real stacktrace, we can be inside Python code
called from Jam code, called from Python code etc. Technically,
it appears possible to interleave stacktraces, something like:

        build_system.py:100
        Jamroot:12
        project.py:70

Comments?

-- 
Vladimir Prus
http://vladimir_prus.blogspot.com
Boost.Build V2: http://boost.org/boost-build2

Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk