Errors can occur during the processing of a message. Some errors can be detected statically, such as those due to problems with message syntax, violations of requirements in the data model, or requirements defined by a function. Other errors might be detected during selection or formatting of a given message. Where available, the use of validation tools is recommended, as early detection of errors makes their correction easier.
Syntax Errors and Data Model Errors apply to all message processors, and MUST be emitted as soon as possible. The other error categories are only emitted during formatting, but it might be possible to detect them with validation tools.
During selection and formatting, expression handlers MUST only emit Message Function Errors.
Implementations do not have to check for or emit Resolution Errors or Message Function Errors in expressions that are not otherwise used by the message, such as placeholders in unselected patterns or declarations that are never referenced during formatting.
When formatting a message with one or more errors, an implementation MUST provide a mechanism to discover and identify at least one of the errors. The exact form of error signaling is implementation defined. Some examples include throwing an exception, returning an error code, or providing a function or method for enumerating any errors.
For all valid messages, an implementation MUST enable a user to get a formatted result. The formatted result might include fallback values such as when a placeholder's expression produced an error during formatting.
The two above requirements MAY be fulfilled by a single formatting method, or separately by more than one such method.
When a message contains more than one error, or contains some error which leads to further errors, an implementation which does not emit all of the errors SHOULD prioritise Syntax Errors and Data Model Errors over others.
When an error occurs while resolving a selector
or calling MatchSelectorKeys with its resolved value,
the selector MUST NOT match any variant key other than the catch-all *
and a Bad Selector error MUST be emitted.
Syntax Errors occur when the syntax representation of a message is not well-formed.
Example invalid messages resulting in a Syntax Error:
{{Missing end braces
{{Missing one end brace}
Unknown {{expression}}
.local $var = {|no message body|}
Data Model Errors occur when a message is not valid due to violating one of the semantic requirements on its structure.
A Variant Key Mismatch occurs when the number of keys on a variant does not equal the number of selectors.
Example invalid messages resulting in a Variant Key Mismatch error:
.input {$one :ns:func} .match $one 1 2 {{Too many}} * {{Otherwise}}
.input {$one :ns:func} .input {$two :ns:func} .match $one $two 1 2 {{Two keys}} * {{Missing a key}} * * {{Otherwise}}
A Missing Fallback Variant error occurs when the message does not include a variant with only catch-all keys.
Example invalid messages resulting in a Missing Fallback Variant error:
.input {$one :ns:func} .match $one 1 {{Value is one}} 2 {{Value is two}}
.input {$one :ns:func} .input {$two :ns:func} .match $one $two 1 * {{First is one}} * 1 {{Second is one}}
A Missing Selector Annotation error occurs when the message contains a selector that does not directly or indirectly reference a declaration with a function.
Examples of invalid messages resulting in a Missing Selector Annotation error:
.match $one 1 {{Value is one}} * {{Value is not one}}
.local $one = {|The one|} .match $one 1 {{Value is one}} * {{Value is not one}}
.input {$one} .match $one 1 {{Value is one}} * {{Value is not one}}
A Duplicate Declaration error occurs when a variable is declared more than once. Note that an input variable is implicitly declared when it is first used, so explicitly declaring it after such use is also an error.
Examples of invalid messages resulting in a Duplicate Declaration error:
.input {$var :number maximumFractionDigits=0} .input {$var :number minimumFractionDigits=0} {{Redeclaration of the same variable}} .local $var = {$ext :number maximumFractionDigits=0} .input {$var :number minimumFractionDigits=0} {{Redeclaration of a local variable}} .input {$var :number minimumFractionDigits=0} .local $var = {$ext :number maximumFractionDigits=0} {{Redeclaration of an input variable}} .input {$var :number minimumFractionDigits=$var2} .input {$var2 :number} {{Redeclaration of the implicit input variable $var2}} .local $var = {$ext :ns:func} .local $var = {$error} .local $var2 = {$var2 :ns:error} {{{$var} cannot be redefined. {$var2} cannot refer to itself}}
A Duplicate Option Name error occurs when the same identifier appears on the left-hand side of more than one option in the same expression.
Examples of invalid messages resulting in a Duplicate Option Name error:
Value is {42 :number style=percent style=decimal}
.local $foo = {horse :ns:func one=1 two=2 one=1} {{This is {$foo}}}
A Duplicate Variant error occurs when the same list of keys is used for more than one variant.
Examples of invalid messages resulting in a Duplicate Variant error:
.input {$var :string} .match $var * {{The first default}} * {{The second default}}
.input {$x :string} .input {$y :string} .match $x $y * foo {{The first "foo" variant}} bar * {{The "bar" variant}} * |foo| {{The second "foo" variant}} * * {{The default variant}}
Resolution Errors occur when the runtime value of a part of a message cannot be determined.
An Unresolved Variable error occurs when a variable reference cannot be resolved.
For example, attempting to format either of the following messages would result in an Unresolved Variable error if done within a context that does not provide for the variable reference
$var
to be successfully resolved:The value is {$var}.
.input {$var :ns:func} .match $var 1 {{The value is one.}} * {{The value is not one.}}
An Unknown Function error occurs when an expression includes a reference to a function which cannot be resolved.
For example, attempting to format either of the following messages would result in an Unknown Function error if done within a context that does not provide for the function
:ns:func
to be successfully resolved:The value is {horse :ns:func}.
.local $horse = {|horse| :ns:func} .match $horse 1 {{The value is one.}} * {{The value is not one.}}
A Bad Selector error occurs when a message includes a selector with a resolved value which does not support selection.
For example, attempting to format this message would result in a Bad Selector error:
.local $day = {|2024-05-01| :date} .match $day * {{The due date is {$day}}}
A Message Function Error is any error that occurs when calling a function handler or which depends on validation associated with a specific function.
Implementations SHOULD provide a way for function handlers to emit (or cause to be emitted) any of the types of error defined in this section. Implementations MAY also provide implementation-defined Message Function Error types.
For example, attempting to format any of the following messages might result in a Message Function Error if done within a context that
- Provides for the variable reference
$user
to resolve to an object{ name: 'Kat', id: 1234 }
,- Provides for the variable reference
$field
to resolve to a string'address'
, and- Uses a
:ns:get
message function which requires its argument to be an object and an optionfield
to be provided with a string value.The exact type of Message Function Error is determined by the function handler.
Hello, {horse :ns:get field=name}!
Hello, {$user :ns:get}!
.local $id = {$user :ns:get field=id} {{Hello, {$id :ns:get field=name}!}}
Your {$field} is {$id :ns:get field=$field}
A Bad Operand error is any error that occurs due to the content or format of the operand, such as when the operand provided to a function during function resolution does not match one of the expected implementation-defined types for that function; or in which a literal operand value does not have the required format and thus cannot be processed into one of the expected implementation-defined types for that specific function.
For example, the following messages each produce a Bad Operand error because the literal
|horse|
does not match thenumber-literal
production, which is a requirement of the function:number
for its operand:.local $horse = {|horse| :number} {{You have a {$horse}.}}
.local $horse = {|horse| :number} .match $horse 1 {{The value is one.}} * {{The value is not one.}}
A Bad Option error is an error that occurs when there is an implementation-defined error with an option or its value. These might include:
- A required option is missing.
- Mutually exclusive options are supplied.
- An option value provided to a function during function resolution does not match one of the implementation-defined types or values for that function; or in which the literal option value does not have the required format and thus cannot be processed into one of the expected implementation-defined types for that specific function.
For example, the following message might produce a Bad Option error because the literal
foo
does not match the productiondigit-size-option
, which is a requirement of the function:number
for itsminimumFractionDigits
option:The answer is {42 :number minimumFractionDigits=foo}.
A Bad Variant Key error is an error that occurs when a variant key does not match the expected implementation-defined format.
For example, the following message produces a Bad Variant Key error because
horse
is not a recognized plural category and does not match thenumber-literal
production, which is a requirement of the:number
function:.local $answer = {42 :number} .match $answer 1 {{The value is one.}} horse {{The value is a horse.}} * {{The value is not one.}}
A Unsupported Operation error is an implementation-specific error that occurs when a given option, option value, operand value, or some combination of these are incompatible or not supported by a given function or its function handler.