Gentoo Development Guide
Error Handling
Importance of Error Handling
Decent error handling is important because:
- Errors must be detected before portage tries to install a broken or incomplete package onto the live filesystem. If build failures aren't caught, a working package could be unmerged and replaced with nothing.
-
When receiving bug reports, it is a lot easier to figure out what went wrong
if you know exactly which call caused the error, rather than just knowing
that, say, something somewhere in
src_compilebroke. - Good error handling and notification can help cut down on the number of bug reports received for a package.
The die Function
The die function should be used to indicate a fatal error and abort the
build. Its parameters should be the message to display.
Although die will work with no parameters, a short message should always be
provided to ease error identification. This is especially important when a
function can die in multiple places.
Some portage-provided functions will automatically die upon failure. Others will
not. It is for example safe to omit the || die after a call to epatch,
but not emake. The reason is that external binaries are not able to call
die that is a bash function. You can see what commands are external binaries
with ls /usr/lib*/portage/bin/ebuild-helpers. In EAPI>=4 all ebuild-helpers automatically die upon failure.
Sometimes displaying additional error information beforehand can be useful. Use
eerror to do this. See Messages.
It's best to use || die too often than too little.
die and Subshells
Warning
die will not work in a subshell.
The following code will not work as expected, since the die is inside a
subshell:
[[ -f foorc ]] && ( update_foorc || die "Couldn't update foorc!" )
The correct way to rewrite this is to use an if block:
if [[ -f foorc ]] ; then
update_foorc || die "Couldn't update foorc!"
fi
When using pipes, a subshell is introduced, so the following is unsafe:
cat list | while read file ; do epatch ${file} ; done
Using input redirection (see Abuse of cat) avoids this problem:
while read file ; do epatch ${file} ; done < list
The assert Function and $PIPESTATUS
When using pipes, simple conditionals and tests upon $? will not correctly
detect errors occurring in anything except the final command in the chain. To get
around this, bash provides the $PIPESTATUS variable, and portage
provides the assert function to check this variable.
bunzip2 "${DISTDIR}/${VIM_RUNTIME_SNAP}" | tar xf
assert
If you need the gory details of $PIPESTATUS, see the bash manpage. Most of the
time, assert is enough.