Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor errors, adding section for Message Function Errors #774

Merged
merged 10 commits into from
May 13, 2024
74 changes: 49 additions & 25 deletions spec/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ 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_.
During selection and formatting,
_expression_ handlers MUST only emit _Message Function Errors_.
aphillips marked this conversation as resolved.
Show resolved Hide resolved
eemeli marked this conversation as resolved.
Show resolved Hide resolved

_Resolution Errors_ and _Formatting Errors_ in _expressions_ that are not used
_Resolution Errors_ and _Message Function 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.
eemeli marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -34,7 +34,7 @@ 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.
and a _Resolution Error_ or a _Message Function Error_ MUST be emitted.
aphillips marked this conversation as resolved.
Show resolved Hide resolved

## Syntax Errors

Expand Down Expand Up @@ -241,49 +241,73 @@ or for private implementation use that is not supported by the current implement
> * {{The value is not one.}}
> ```

### Invalid Expression
### Unsupported Statement

An **_<dfn>Unsupported Statement</dfn>_** 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}}
> ```
eemeli marked this conversation as resolved.
Show resolved Hide resolved

An **_<dfn>Invalid Expression</dfn>_** error occurs when a _message_ includes an _expression_
## Message Function Errors
eemeli marked this conversation as resolved.
Show resolved Hide resolved
aphillips marked this conversation as resolved.
Show resolved Hide resolved

A **_<dfn>Message Function Error</dfn>_** is any error that occurs
when calling a message function implementation
Comment on lines +273 to +274
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this use of the singular, and would suggest that the previous part of this document be updated accordingly (but for consistency, I think similar phrasing should be used for all sections in this PR).

or which depend on validation associated with a specific function.
eemeli marked this conversation as resolved.
Show resolved Hide resolved

### Bad Expression

A **_<dfn>Bad Expression</dfn>_** error occurs when a _message_ includes an _expression_
eemeli marked this conversation as resolved.
Show resolved Hide resolved
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 **_<dfn>Operand Mismatch Error</dfn>_** is an _Invalid Expression_ error that occurs when
### Bad Operand
aphillips marked this conversation as resolved.
Show resolved Hide resolved

A **_<dfn>Bad Operand</dfn>_** error is an 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)
> For example, the following _message_ produces a _Bad Operand_ error
> because the literal `|horse|` does not match the production `number-literal`,
> which is a requirement of the function `:number` for its operand:
>
> ```
> .local $horse = {horse :number}
> {{You have a {$horse}.}}
> ```
eemeli marked this conversation as resolved.
Show resolved Hide resolved
> 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.}}
>```

### Unsupported Statement
### Bad Option

An **_<dfn>Unsupported Statement</dfn>_** error occurs when a message includes a _reserved statement_.
A **_<dfn>Bad Option</dfn>_** 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 for that _function_;
eemeli marked this conversation as resolved.
Show resolved Hide resolved
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_.
- Any other implementation-defined errors related to _options_.
eemeli marked this conversation as resolved.
Show resolved Hide resolved

> For example, attempting to format this message
> would always result in an _Unsupported Statement_ error:
> For example, the following _message_ might produce a _Bad Option_ error
> because the literal `foo` does not match the production `digit-size-option`,
> which is a requirement of the function `:number` for its `minimumFractionDigits` _option_:
>
> ```
> .some {|horse|}
> {{The message body}}
> The answer is {42 :number minimumFractionDigits=foo}.
> ```

## Selection Errors
### Selection Error

**_<dfn>Selection Errors</dfn>_** occur when message selection fails.
A **_<dfn>Selection Error</dfn>_** occurs 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
eemeli marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -302,9 +326,9 @@ An **_<dfn>Unsupported Statement</dfn>_** error occurs when a message includes a
> * {{The value is not one.}}
> ```

## Formatting Errors
### Formatting Error

**_<dfn>Formatting Errors</dfn>_** occur during the formatting of a resolved value,
A **_<dfn>Formatting Error</dfn>_** occurs during the formatting of a resolved value,
for example when encountering a value with an unsupported type
or an internally inconsistent set of options.
eemeli marked this conversation as resolved.
Show resolved Hide resolved
eemeli marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
10 changes: 5 additions & 5 deletions spec/formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ the following steps are taken:
argument type `T` and return type `U`
for implementations of functions
such that `U` can be coerced to `T`.
Implementations of a _function_ SHOULD emit an
_Invalid Expression_ error for _operands_ whose resolved value
Implementations of a _function_ SHOULD emit a
_Bad Operand_ error for _operands_ whose resolved value
or type is not supported.

> [!NOTE]
Expand Down Expand Up @@ -307,13 +307,13 @@ the following steps are taken:
resolve the value of the _expression_ as the result of that function call.

If the call fails or does not return a valid value,
emit a _Invalid Expression_ error.
emit a _Message Function Error_.
eemeli marked this conversation as resolved.
Show resolved Hide resolved

Implementations MAY provide a mechanism for the _function_ to provide
additional detail about internal failures.
Specifically, if the cause of the failure was that the datatype, value, or format of the
_operand_ did not match that expected by the _function_,
the _function_ might cause an _Operand Mismatch Error_ to be emitted.
the _function_ might cause a _Bad Operand_ error to be emitted.

In all failure cases, use the _fallback value_ for the _expression_ as the resolved value.

Expand Down Expand Up @@ -735,7 +735,7 @@ each _text_ and _placeholder_ part of the selected _pattern_ is resolved and for

Resolved values cannot always be formatted by a given implementation.
When such an error occurs during _formatting_,
an implementation SHOULD emit a _Formatting Error_ and produce a
an implementation SHOULD emit a _Message Function Error_ and produce a
eemeli marked this conversation as resolved.
Show resolved Hide resolved
eemeli marked this conversation as resolved.
Show resolved Hide resolved
_fallback value_ for the _placeholder_ that produced the error.
A formatting function MAY substitute a value to use instead of a _fallback value_.

Expand Down
16 changes: 8 additions & 8 deletions spec/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ The function `:string` provides string selection and formatting.
The _operand_ of `:string` is either any implementation-defined type
that is a string or for which conversion to a string is supported,
or any _literal_ value.
All other values produce an _Invalid Expression_ error.
All other values produce a _Bad Operand_ error.

> For example, in Java, implementations of the `java.lang.CharSequence` interface
> (such as `java.lang.String` or `java.lang.StringBuilder`),
Expand Down Expand Up @@ -600,7 +600,7 @@ The _function_ `:integer` performs selection as described in [Number Selection](

The _operand_ of a number function is either an implementation-defined type or
a literal whose contents match the `number-literal` production in the [ABNF](/spec/message.abnf).
All other values produce an _Invalid Expression_ error.
All other values produce a _Bad Operand_ error.

> For example, in Java, any subclass of `java.lang.Number` plus the primitive
> types (`byte`, `short`, `int`, `long`, `float`, `double`, etc.)
Expand Down Expand Up @@ -776,15 +776,15 @@ If no options are specified, this function defaults to the following:
The _operand_ of the `:datetime` function is either
an implementation-defined date/time type
or a _date/time literal value_, as defined in [Date and Time Operand](#date-and-time-operands).
All other _operand_ values produce an _Invalid Expression_ error.
All other _operand_ values produce a _Bad Operand_ error.

#### Options

The `:datetime` function can use either the appropriate _style options_
or can use a collection of _field options_ (but not both) to control the formatted
output.

If both are specified, an _Invalid Expression_ error MUST be emitted
If both are specified, a _Bad Option_ error MUST be emitted
aphillips marked this conversation as resolved.
Show resolved Hide resolved
and a _fallback value_ used as the resolved value of the _expression_.

> [!NOTE]
Expand Down Expand Up @@ -901,7 +901,7 @@ If no options are specified, this function defaults to the following:
The _operand_ of the `:date` function is either
an implementation-defined date/time type
or a _date/time literal value_, as defined in [Date and Time Operand](#date-and-time-operands).
All other _operand_ values produce an _Invalid Expression_ error.
All other _operand_ values produce a _Bad Operand_ error.

#### Options

Expand All @@ -924,7 +924,7 @@ If no options are specified, this function defaults to the following:
The _operand_ of the `:time` function is either
an implementation-defined date/time type
or a _date/time literal value_, as defined in [Date and Time Operand](#date-and-time-operands).
All other _operand_ values produce an _Invalid Expression_ error.
All other _operand_ values produce a _Bad Operand_ error.

#### Options

Expand All @@ -941,7 +941,7 @@ The function `:time` has these _options_:
The _operand_ of a date/time function is either
an implementation-defined date/time type
or a _date/time literal value_, as defined below.
All other _operand_ values produce an _Invalid Expression_ error.
All other _operand_ values produce a _Bad Operand_ error.

A **_<dfn>date/time literal value</dfn>_** is a non-empty string consisting of an ISO 8601 date,
or an ISO 8601 datetime optionally followed by a timezone offset.
Expand All @@ -963,7 +963,7 @@ For more information, see [Working with Timezones](https://w3c.github.io/timezon
> The [ABNF](/spec/message.abnf) and [syntax](/spec/syntax.md) of MF2
> do not formally define date/time literals.
> This means that a _message_ can be syntactically valid but produce
> an _Operand Mismatch Error_ at runtime.
> a _Bad Operand_ error at runtime.

> [!NOTE]
> String values passed as variables in the _formatting context_'s
Expand Down