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, an expression handler MUST only emit Resolution Errors and Selection Errors. During formatting, an expression handler MUST only emit Resolution Errors and Formatting Errors.
Resolution Errors and Formatting Errors in expressions that are not used in pattern selection or formatting MAY be ignored, as they do not affect the output of the formatter.
In all cases, when encountering a runtime error, a message formatter MUST provide some representation of the message. An informative error or errors MUST also be separately provided.
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 within a selector,
the selector MUST NOT match any variant key other than the catch-all *
and a Resolution Error or a Selection 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 invalid 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:
.match {$one :func} 1 2 {{Too many}} * {{Otherwise}}
.match {$one :func} {$two :func} 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:
.match {$one :func} 1 {{Value is one}} 2 {{Value is two}}
.match {$one :func} {$two :func} 1 * {{First is one}} * 1 {{Second is one}}
A Missing Selector Annotation error occurs when the message contains a selector that does not have an annotation, or contains a variable that does not directly or indirectly reference a declaration with an annotation.
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 :someFunction} .local $var = {$error} .local $var2 = {$var2 :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 :func one=1 two=2 one=1} {{This is {$foo}}}
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}.
.match {$var :func} 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
:func
to be successfully resolved:The value is {horse :func}.
.match {|horse| :func} 1 {{The value is one.}} * {{The value is not one.}}
An Unsupported Expression error occurs when an expression uses syntax reserved for future standardization, or for private implementation use that is not supported by the current implementation.
For example, attempting to format this message would always result in an Unsupported Expression error:
The value is {!horse}.
Attempting to format this message would result in an Unsupported Expression error if done within a context that does not support the
^
private use sigil:.match {|horse| ^private} 1 {{The value is one.}} * {{The value is not one.}}
An Invalid Expression error occurs when a message includes an expression
whose implementation-defined internal requirements produce an error during function resolution
or when a function returns a value (such as null
) that the implementation does not support.
An Operand Mismatch Error is an Invalid Expression error that occurs when an 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 message produces an Operand Mismatch Error (a type of Invalid Expression error) because the literal
|horse|
does not match the productionnumber-literal
, which is a requirement of the function:number
for its operand:.local $horse = {horse :number} {{You have a {$horse}.}}
The following message might produce an Invalid Expression error if the the function
:function
threw an exception or otherwise emitted an error rather than returning a valid value:{{This has an invalid expression {$var :function} because it has a bug in it.}}
An Unsupported Statement error occurs when a message includes a reserved statement.
For example, attempting to format this message would always result in an Unsupported Statement error:
.some {|horse|} {{The message body}}
Selection Errors occur when message selection fails.
For example, attempting to format either of the following messages might result in a Selection Error if done within a context that uses a
:number
selector function which requires its input to be numeric:.match {|horse| :number} 1 {{The value is one.}} * {{The value is not one.}}
.local $sel = {|horse| :number} .match {$sel} 1 {{The value is one.}} * {{The value is not one.}}
Formatting Errors occur during the formatting of a resolved value, for example when encountering a value with an unsupported type or an internally inconsistent set of options.
For example, attempting to format any of the following messages might result in a Formatting 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
:get
formatting function which requires its argument to be an object and an optionfield
to be provided with a string value,Hello, {horse :get field=name}!
Hello, {$user :get}!
.local $id = {$user :get field=id} {{Hello, {$id :get field=name}!}}
Your {$field} is {$id :get field=$field}