langur exceptions

An exception in langur is always a hash that is guaranteed to contain certain fields, even if they are empty. You may include other fields in a hash that you throw. You can also throw anything else and it becomes the required hash.

If you do not specify a source in what you throw, langur sometimes determines and adds the function name automatically.

exception hash

Any exception hash is guaranteed to contain the following fields.

"cat" an exception general category string
"msg" the message string
"src" exception source string
"hst" previous exception or null

catching exceptions

... catch [_err] { ... } [ else if { ... } ] [ else { ... } ]

There is no explicit try block. All the statements preceding a catch within a block are the implicit try block. You could put a catch at the end of a script to cover the entire script.

If a catch is embedded within a catch, they may each use the same exception variable name as they each have their own scope.

If you do not rethrow a caught exception, it is not propogated past the catch.

Using throw within a catch expression does not require you to specify what to throw. It implicitly rethrows the caught exception.

If an exception variable is not specified, it is implicitly _err. Prior to 0.7, the default exception variable was .err.

catch else

An else section is optional. It will only be run if there is no exception.

As of 0.7, you can also use else if on catch.

Catch and else have scope. Since try does not have scope, variables declared within the implicit try section but still in scope after the catch will be the default value (null) if they are not initialized before an exception.

catch exception example

123 / 0 catch .err { if .err["cat"] == "math" { 456 } else { throw } } else { # no exception 890 } # result == 456

simple catch

Using catch without curly braces was previously allowed in some circumstances, as a shortened form. With 0.11.4, this syntax is no longer allowed, for clarity (curly braces always required).

With 0.12, you can use simple catch, using a colon.

The example above could almost be written as follows (leaving out an else section), using the implicit _err variable, and using simple catch.

123 / 0 catch : if _err["cat"] == "math" { 456 } else { throw }

Curly braces are required on the catch expression if you want to use an else section. The else shown in this example goes with the if expression, not the catch.

still want try/catch?

You can emulate a try block by wrapping into a scoped block.

{ ... catch .e { ... } }

Go panics

While a panic (a Go language exception) could indicate a bug in langur, we decided it best to catch them and convert them to langur exceptions. This still does not work with out-of-memory (OOM) errors. As a concise explanation, someone wrote "All OOM conditions terminate a Go program."

If a Go panic occurs and is caught and converted to a langur exception, the source name starts with "panic:" and may or may not have more information.