Skip to contentSkip to conversation

bb.cookerdata: don't show traceback for ParseError/ExpansionError

PATCH In review Christopher Larson 2 participants 3 messages Jul 31, 2015

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 bb.cookerdata: don't show traceback for ParseError/ExpansionError

From: Christopher Larson <[email protected]>

Tracebacks are of extremely limited usefulness in this context. The exceptions carry the necessary context already, and the user doesn't care about the calls in bitbake internals that led to an expansion or parse failure.

---
 lib/bb/cookerdata.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
lib/bb/cookerdata.py +5 -2
index 0ca87a0..57fc6bb 100644
@@ -173,9 +173,12 @@ def catch_parse_error(func):
     def wrapped(fn, *args):
         try:
             return func(fn, *args)
-        except (IOError, bb.parse.ParseError, bb.data_smart.ExpansionError) as exc:
+        except IOError as exc:
             import traceback
-            parselog.critical( traceback.format_exc())
+            parselog.critical(traceback.format_exc())
+            parselog.critical("Unable to parse %s: %s" % (fn, exc))
+            sys.exit(1)
+        except (bb.parse.ParseError, bb.data_smart.ExpansionError) as exc:
             parselog.critical("Unable to parse %s: %s" % (fn, exc))
             sys.exit(1)
     return wrapped
Signature · 1 line
2.2.1
#1 lore raw

PATCH 2/2 bb.parse: properly error out on filesystem errors

From: Christopher Larson <[email protected]>

We've had a long-standing bug where a legitimate error reading a file (IOError or OSError) is always suppressed as though it was a 'file not found' case. As a concrete example, if you do a chmod 000 conf/local.conf, it'll silently not parse local.conf, rather than erroring to let the user know about the problem.

Fix this by handling the ENOENT case specifically.

---
 lib/bb/parse/__init__.py             |  7 ++++---
 lib/bb/parse/parse_py/ConfHandler.py | 21 ++++++++++++++-------
 2 files changed, 18 insertions(+), 10 deletions(-)
lib/bb/parse/__init__.py +4 -3
index 4a78e18..1becaa4 100644
@@ -26,9 +26,10 @@ File parsers for the BitBake build tools.
 
 handlers = []
 
+import errno
+import logging
 import os
 import stat
-import logging
 import bb
 import bb.utils
 import bb.siggen
@@ -122,12 +123,12 @@ def resolve_file(fn, d):
         for af in attempts:
             mark_dependency(d, af)
         if not newfn:
-            raise IOError("file %s not found in %s" % (fn, bbpath))
+            raise IOError(errno.ENOENT, "file %s not found in %s" % (fn, bbpath))
         fn = newfn
 
     mark_dependency(d, fn)
     if not os.path.isfile(fn):
-        raise IOError("file %s not found" % fn)
+        raise IOError(errno.ENOENT, "file %s not found" % fn)
 
     return fn
 
lib/bb/parse/parse_py/ConfHandler.py +14 -7
index 250a557..fbd75b1 100644
@@ -24,8 +24,9 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-import re, os
-import logging
+import errno
+import re
+import os
 import bb.utils
 from bb.parse import ParseError, resolve_file, ast, logger, handle
 
@@ -92,11 +93,17 @@ def include(parentfn, fn, lineno, data, error_out):
         logger.warn("Duplicate inclusion for %s in %s" % (fn, data.getVar('FILE', True)))
 
     try:
-        ret = bb.parse.handle(fn, data, True)
-    except (IOError, OSError):
-        if error_out:
-            raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), parentfn, lineno)
-        logger.debug(2, "CONF file '%s' not found", fn)
+        bb.parse.handle(fn, data, True)
+    except (IOError, OSError) as exc:
+        if exc.errno == errno.ENOENT:
+            if error_out:
+                raise ParseError("Could not %s file %s" % (error_out, fn), parentfn, lineno)
+            logger.debug(2, "CONF file '%s' not found", fn)
+        else:
+            if error_out:
+                raise ParseError("Could not %s file %s: %s" % (error_out, fn, exc.strerror), parentfn, lineno)
+            else:
+                raise ParseError("Error parsing %s: %s" % (fn, exc.strerror), parentfn, lineno)
 
 # We have an issue where a UI might want to enforce particular settings such as
 # an empty DISTRO variable. If configuration files do something like assigning
Signature · 1 line
2.2.1
#2 lore raw
In reply to Christopher Larson
Quoted 9 lines · Christopher Larson

From: Christopher Larson <[email protected]>

Tracebacks are of extremely limited usefulness in this context. The exceptions
carry the necessary context already, and the user doesn't care about the calls
in bitbake internals that led to an expansion or parse failure.

Example of a parse error:

ERROR: Traceback (most recent call last):
File "/scratch/poky/bitbake/lib/bb/cookerdata.py", line 175, in
wrapped
return func(fn, *args)
File "/scratch/poky/bitbake/lib/bb/cookerdata.py", line 185, in
parse_config_file
return bb.parse.handle(fn, data, include)
File "/scratch/poky/bitbake/lib/bb/parse/__init__.py", line 108, in
handle
return h['handle'](fn, data, include)
File "/scratch/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py",
line 155, in handle
statements.eval(data)
File "/scratch/poky/bitbake/lib/bb/parse/ast.py", line 39, in eval
statement.eval(data)
File "/scratch/poky/bitbake/lib/bb/parse/ast.py", line 63, in eval
bb.parse.ConfHandler.include(self.filename, s, self.lineno, data,
False)
File "/scratch/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py",
line 106, in include
raise ParseError("Error parsing %s: %s" % (fn, exc.strerror),
parentfn, lineno)
ParseError: ParseError at /scratch/poky/meta/conf/bitbake.conf:679:
Error parsing /scratch/build/conf/local.conf: Permission denied

ERROR: Unable to parse conf/bitbake.conf: ParseError at /scratch/poky/meta/conf/bitbake.conf:679: Error parsing /scratch/build/conf/local.
conf: Permission denied

Example of an expansion error:

ERROR: Traceback (most recent call last):
File "/scratch/poky/bitbake/lib/bb/cookerdata.py", line 175, in
wrapped
return func(fn, *args)
File "/scratch/poky/bitbake/lib/bb/cookerdata.py", line 185, in
parse_config_file
return bb.parse.handle(fn, data, include)
File "/scratch/poky/bitbake/lib/bb/parse/__init__.py", line 108, in
handle
return h['handle'](fn, data, include)
File "/scratch/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py",
line 155, in handle
statements.eval(data)
File "/scratch/poky/bitbake/lib/bb/parse/ast.py", line 39, in eval
statement.eval(data)
File "/scratch/poky/bitbake/lib/bb/parse/ast.py", line 63, in eval
bb.parse.ConfHandler.include(self.filename, s, self.lineno, data,
False)
File "/scratch/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py",
line 96, in include
bb.parse.handle(fn, data, True)
File "/scratch/poky/bitbake/lib/bb/parse/__init__.py", line 108, in
handle
return h['handle'](fn, data, include)
File "/scratch/poky/bitbake/lib/bb/parse/parse_py/ConfHandler.py",
line 155, in handle
statements.eval(data)
File "/scratch/poky/bitbake/lib/bb/parse/ast.py", line 39, in eval
statement.eval(data)
File "/scratch/poky/bitbake/lib/bb/parse/ast.py", line 111, in eval
val = e.expand(groupd["value"], key + "[:=]")
File "/scratch/poky/bitbake/lib/bb/data_smart.py", line 380, in expand
return self.expandWithRefs(s, varname).value
File "/scratch/poky/bitbake/lib/bb/data_smart.py", line 370, in
expandWithRefs
raise ExpansionError(varname, s, exc)
ExpansionError: Failure expanding variable FOO[:=], expression was
${@alpha beta theta} which triggered exception SyntaxError: invalid syntax (FOO[:=], line 1)

ERROR: Unable to parse conf/bitbake.conf: Failure expanding variable
FOO[:=], expression was ${@alpha beta theta} which triggered exception
SyntaxError: invalid syntax (FOO[:=]

    , line 1)
Signature · 5 lines
Christopher Larson
kergoth at gmail dot com
Founder - BitBake, OpenEmbedded, OpenZaurus
Maintainer - Tslib
Senior Software Engineer, Mentor Graphics