Warning: Work in progress! Leave feedback on Zulip or Github if you'd like this doc to be updated.

List of Errors in the OSH Interpreter

Table of Contents
Fatal vs. Non-Fatal
Strict Modes
Parse Error API
Runtime Error API: error codes + error contexts?
Problem in bash: Context affects a lot
Arith Eval
Bool Eval
Word Eval
Command Exec
Syscall Failures
Interpreter Failures
Runtime Parse Errors
Parse Time Errors

Parse Error: Can be determined statically spec/parse-errors.test.sh

TODO: See test/runtime-errors.sh. Merge them here.

Fatal vs. Non-Fatal

Fatal Error: terminates the interpreter unconditionally, e.g. divide by zero does this in bash.

Non-fatal error: terminates the current builtin and exits 1

non-fatal errors can be turned into fatal errors.

by Strict modes: set -o errexit

strict modes can also things that are not errors at all into fatal errors set -o nounset set -o failglob

Fatal errors can be turned into non-fatal ones!!!!

by dparen:

(( 1 / 0 ))

by command sub -- although this involves another process so it's understandable!

set -o errexit echo $(exit 1)

Strict Modes

strict_array strict_errexit strict_arith

TODO: strict-word-eval? for unicode errors for subshell negative indices? I think this is most consistent right now.

Parse Error API


p_die() internally

w = w_parser.ReadWord()
if w is None:
  do something with w_parser.Error()

Related to memory management API:

# arena is the out param
arena = pool.NewArena()
c_parser = cmd_parse.CommandParser(w_parser, arena)
bool ok = c_parser.Parse()
if ok:
  arena.RootNode() #  turns indexes into pointers?
  arena.Deallocate()  # d
  c_parser.Error()  # Is this still a stack?

Runtime Error API: error codes + error contexts?


List of contexts:

Problem in bash: Context affects a lot

echo $(( 1 / 0 )) echo 'after-$(()) (( 1 / 0 )) echo 'after-$(())

Arith Eval

Divide by zero: $(( 1 / 0 ))


Maybe: integer overflow. But we want big numbers.

Type errors between integers and strings:

$(( x * 2 ))  # doesn't make sense, except in bash's crazy world.

Invalid hex constant:

echo $(( x * 2 ))   (fatal in bash)

Bool Eval

regcomp parse error:

x=$(cat invalid-syntax.txt) [[ foo =~ $x ]]

Word Eval

IMPORTANT: Command sub error $(exit 1)

User-requested error: ${undef?error}

set -o nounset

def _EmptyStrOrError(self, val, token=None):
  # calls `e_die()`

Variants: nounset: index out of bounds ${a[3]} I guess same diagnostic?

In bash you can set an index out of bounds, like b[2]=9
Might want to have a mode for this?

set -o failglob TODO: not implemented might need PWD diagnostic

Redirects: Redirect to empty filename/descriptor ( or array)

{ break; }
^~~~~~ break only invalid inside loop, etc.


Command Exec

IMPORTANT: subshell error ( exit 1 )

set -o errexit -- turns NON-FATAL error into FATAL error.

set -o pipefail pipefail might need some fanciness for ${PIPESTATUS}

Trying to set readonly variable: readonly foo=bar foo=x (could any of this be done at compile time?)

Trying to redeclare a variable? That can also be parse time. local x=1 local x=2

Type errors between Str and StrArray: -- strict-array controls this EvalWordToString calls e_die()`

echo foo > "$@" ^-- # Should have what it evaluated to? # This could be static too

case "$@" in "$@") echo bad;; esac

${undef:-"$@"} is OK, but ${var%"$@"} doesn't make sense really. ${v/"$@"/"$@"}

LHS evaluation: s='abc' s[1]=X # invalid because it's a string, not an array

Invalid descriptor:

fd=$(cat invalid.txt) echo foo 2>& $fd


In core/builtins.py:

return 1

A usage error is a runtime error that results in the builtin returning 1.

Builtin has too many arguments -- but this falls under the errexit rule cd foo bar baz continue "$@" (Parse error: continue 1 2 3)

Although we might want to highlight the extra args.

Syscall Failures

Fatal error from system calls: fork() could fail in theory

Some are not failures:

stat() [[ -f /tmp/foo ]] 
cd /ff  chdir()  # exit code 1
cat <nonexistent  # This is just exit code 1 

Interpreter Failures

Runtime: Stack Too Deep (catch infinite recursion) Out of memory: should not happen with OSH, but maybe with Oil

Runtime Parse Errors

The way bash works 0x$var can be a hex literal. so var=xx makes this invalid. hex/octal/decimal have this problem.

Parse Time Errors

regcomp() errors (sometimes at parse time; other times at runtime)

Need to show stack trace for "source" like Python. Prototype this.

Also might show which token thing caused you to be in arith parse state, like:

$((echo hi)) ^~ ^~ Arith Invalid token

Generated on Sun Jan 19 22:59:37 PST 2020