On this page:
error
error.message
error.Who
error.Clause
error.Clause.msg
error.text
error.val
error.vals
error.annot
error.annot_  msg
error.reindent
8.15.0.12

10.1 Errors🔗ℹ

function

fun error(

  ~exn: exn :: (Function.of_arity(2)

                  || Function.of_arity(3)

                  || Function.of_arity(4))

          = Exn.Fail,

  ~srcloc: srcloc :: maybe(Srcloc) = #false,

  ~who: who :: maybe(error.Who) = #false,

  msg :: ReadableString,

  ~details: details :: [List.of(ReadableString)] = [],

  clause :: error.Clause,

  ...

) :: None

Throws the result of exn as an exception, constructing the error message from srcloc, who, msg, details, and the clauses in order.

If who is not #false, it is added to the beginning of the message, and a :  separator is added in between.

The msg part of the error message is meant to fit on a single line. If details is non-empty, then ; is added to the end of msg, and each element of details is written on its own line with a 1-space prefix.

The clauses are added to the end of the error message. Construct a clause with functions like error.val, error.vals, error.annot, or error.text. Each clause will start on its own line with a 2-space prefix.

When exn is called by error, the first argument is a string message, and the second argument is Continuation.Marks.current(). If exn accepts at least three arguments, then srcloc is provided as the third argument. If exn accepts four arguments, then the list of clauses is provided as the fourth argument.

Conventions for using error:

> error("oops")

oops

> error(~who: #'me, "oops")

me: oops

> error(~who: #'me,

        "oops",

        ~details: ["something has gone wrong;",

                   "see the manual for more information"])

me: oops;

 something has gone wrong;

 see the manual for more information

> error(~who: #'me,

        ~exn: Exn.Fail.Annot,

        error.annot_msg("fruit"),

        error.annot("Tropical"),

        error.val(~label: "fruit", #'Apple))

me: fruit does not satisfy annotation

  annotation: Tropical

  fruit: #’Apple

> error(~who: #'me,

        "mismatch between fruit and vegetable",

        error.val(~label: "fruit", [#'Apple, 0]),

        error.val(~label: "vegetable", [#'Lettuce, -1]))

me: mismatch between fruit and vegetable

  fruit: [#’Apple, 0]

  vegetable: [#’Lettuce, -1]

function

fun error.message(

  ~srcloc: srcloc :: maybe(Srcloc) = #false,

  ~who: who :: maybe(error.Who) = #false,

  msg :: ReadableString,

  ~details: details :: [List.of(ReadableString)] = [],

  clause :: Error.Clause,

  ...

) :: String

Like error, but without the ~exn argument, and the result is a message string instead of throwing an exception.

> error.message(~who: #'me, "oops")

"me: oops"

annotation

error.Who

Satisfied by a ReadableString, Symbol, or Name.

class

class error.Clause(msg :: String):

  nonfinal

 

function

fun error.text(~label: label :: String,

               v :: Any)

  :: error.Clause

 

function

fun error.val(~label: label :: String = "value",

              v :: Any)

  :: error.Clause

 

function

fun error.vals(~label: label :: String = "value",

               v :: Any, ...)

  :: error.Clause

 

function

fun error.annot(~label: label :: String = "annotation",

                annot_str :: String)

  :: error.Clause

An error.Clause represents a piece of an error message that has a label followed by a value or text. The error.text constructor is the most generic one, where the argument v is converted with to_string to include in the message. If the string form of v spans multiple lines, each line will get a 3-space prefix to incorporate it into the message string; see also error.reindent.

The error.val and error.vals function convert each v to a string using repr.

Use error.annot to report an annotation in an error message, where Syntax.to_source_string may be useful (especially in in a macro’s implementation) to construct a suitable string form of an annotation.

The msg field of a error.Clause omits a 2-space prefix that will be added to the clause by error or error.message, but if it spans multiple lines, then msg will include a 3-space prefix on each line after the first one.

> error.text(~label: "name", "Alice")

Clause("name: Alice")

> error.val([1, 2, 3])

Clause("value: [1, 2, 3]")

> error.val(~label: "list", [1, 2, 3])

Clause("list: [1, 2, 3]")

> error.vals(1, 2, 3)

Clause("values:\n   1\n   2\n   3")

> error.annot("List.of(Int)")

Clause("annotation: List.of(Int)")

function

fun error.annot_msg(what :: String = "value")

Constructs the text of a “does not satisfy annotation” error, using what as the noun in the message.

function

fun error.reindent(

  s :~ String,

  ~space: space :: String = " ",

  ~tab: tab :: String = "   ",

  ~label: label :: String = "",

  ~max_len: max_len :: NonnegInt

              = 72 - (2 + label.length() + 1 + space.length())

) :: String

The indentation function used by error.text and related functions. If s has multiple lines or if it is longer than max_len characters, then s is prefixed with a newline, and each line of s is prefixed with tab. Otherwise, s is prefixed with just space.

The label argument is used only to determine the default value of max_len.