|
| 1 | +# MessageFormat 2.0 Errors |
| 2 | + |
| 3 | +Errors in messages and their formatting MAY occur and be detected |
| 4 | +at different stages of processing. |
| 5 | +Where available, |
| 6 | +the use of validation tools is recommended, |
| 7 | +as early detection of errors makes their correction easier. |
| 8 | + |
| 9 | +## Error Handling |
| 10 | + |
| 11 | +_Syntax Errors_ and _Data Model Errors_ apply to all message processors, |
| 12 | +and MUST be emitted as soon as possible. |
| 13 | +The other error categories are only emitted during formatting, |
| 14 | +but it might be possible to detect them with validation tools. |
| 15 | + |
| 16 | +During selection, an _expression_ handler MUST only emit _Resolution Errors_ and _Selection Errors_. |
| 17 | +During formatting, an _expression_ handler MUST only emit _Resolution Errors_ and _Formatting Errors_. |
| 18 | + |
| 19 | +_Resolution Errors_ and _Formatting Errors_ in _expressions_ that are not used |
| 20 | +in _pattern selection_ or _formatting_ MAY be ignored, |
| 21 | +as they do not affect the output of the formatter. |
| 22 | + |
| 23 | +In all cases, when encountering a runtime error, |
| 24 | +a message formatter MUST provide some representation of the message. |
| 25 | +An informative error or errors MUST also be separately provided. |
| 26 | + |
| 27 | +When a message contains more than one error, |
| 28 | +or contains some error which leads to further errors, |
| 29 | +an implementation which does not emit all of the errors |
| 30 | +SHOULD prioritise _Syntax Errors_ and _Data Model Errors_ over others. |
| 31 | + |
| 32 | +When an error occurs within a _selector_, |
| 33 | +the _selector_ MUST NOT match any _variant_ _key_ other than the catch-all `*` |
| 34 | +and a _Resolution Error_ or a _Selection Error_ MUST be emitted. |
| 35 | + |
| 36 | +## Syntax Errors |
| 37 | + |
| 38 | +**_<dfn>Syntax Errors</dfn>_** occur when the syntax representation of a message is not well-formed. |
| 39 | + |
| 40 | +> Example invalid messages resulting in a _Syntax Error_: |
| 41 | +> |
| 42 | +> ``` |
| 43 | +> {{Missing end braces |
| 44 | +> ``` |
| 45 | +> |
| 46 | +> ``` |
| 47 | +> {{Missing one end brace} |
| 48 | +> ``` |
| 49 | +> |
| 50 | +> ``` |
| 51 | +> Unknown {{expression}} |
| 52 | +> ``` |
| 53 | +> |
| 54 | +> ``` |
| 55 | +> .local $var = {|no message body|} |
| 56 | +
B41A
span>> ``` |
| 57 | +
|
| 58 | +## Data Model Errors |
| 59 | +
|
| 60 | +**_<dfn>Data Model Errors</dfn>_** occur when a message is invalid due to |
| 61 | +violating one of the semantic requirements on its structure. |
| 62 | +
|
| 63 | +### Variant Key Mismatch |
| 64 | +
|
| 65 | +A **_<dfn>Variant Key Mismatch</dfn>_** occurs when the number of keys on a _variant_ |
| 66 | +does not equal the number of _selectors_. |
| 67 | +
|
| 68 | +> Example invalid messages resulting in a _Variant Key Mismatch_ error: |
| 69 | +> |
| 70 | +> ``` |
| 71 | +> .match {$one :func} |
| 72 | +> 1 2 {{Too many}} |
| 73 | +> * {{Otherwise}} |
| 74 | +> ``` |
| 75 | +> |
| 76 | +> ``` |
| 77 | +> .match {$one :func} {$two :func} |
| 78 | +> 1 2 {{Two keys}} |
| 79 | +> * {{Missing a key}} |
| 80 | +> * * {{Otherwise}} |
| 81 | +> ``` |
| 82 | +
|
| 83 | +### Missing Fallback Variant |
| 84 | +
|
| 85 | +A **_<dfn>Missing Fallback Variant</dfn>_** error occurs when the message |
| 86 | +does not include a _variant_ with only catch-all keys. |
| 87 | +
|
| 88 | +> Example invalid messages resulting in a _Missing Fallback Variant_ error: |
| 89 | +> |
| 90 | +> ``` |
| 91 | +> .match {$one :func} |
| 92 | +> 1 {{Value is one}} |
| 93 | +> 2 {{Value is two}} |
| 94 | +> ``` |
| 95 | +> |
| 96 | +> ``` |
| 97 | +> .match {$one :func} {$two :func} |
| 98 | +> 1 * {{First is one}} |
| 99 | +> * 1 {{Second is one}} |
| 100 | +> ``` |
| 101 | +
|
| 102 | +### Missing Selector Annotation |
| 103 | +
|
| 104 | +A **_<dfn>Missing Selector Annotation</dfn>_** error occurs when the _message_ |
| 105 | +contains a _selector_ that does not have an _annotation_, |
| 106 | +or contains a _variable_ that does not directly or indirectly reference a _declaration_ with an _annotation_. |
| 107 | +
|
| 108 | +> Examples of invalid messages resulting in a _Missing Selector Annotation_ error: |
| 109 | +> |
| 110 | +> ``` |
| 111 | +> .match {$one} |
| 112 | +> 1 {{Value is one}} |
| 113 | +> * {{Value is not one}} |
| 114 | +> ``` |
| 115 | +> |
| 116 | +> ``` |
| 117 | +> .local $one = {|The one|} |
| 118 | +> .match {$one} |
| 119 | +> 1 {{Value is one}} |
| 120 | +> * {{Value is not one}} |
| 121 | +> ``` |
| 122 | +> |
| 123 | +> ``` |
| 124 | +> .input {$one} |
| 125 | +> .match {$one} |
| 126 | +> 1 {{Value is one}} |
| 127 | +> * {{Value is not one}} |
| 128 | +> ``` |
| 129 | +
|
| 130 | +### Duplicate Declaration |
| 131 | +
|
| 132 | +A **_<dfn>Duplicate Declaration</dfn>_** error occurs when a _variable_ appears in two _declarations_. |
| 133 | +This includes when an _input-declaration_ binds a _variable_ that appears in a previous _declaration_, |
| 134 | +when a _local-declaration_ binds a _variable_ that appears in a previous _declaration_, |
| 135 | +or when a _local-declaration_ refers to its bound _variable_ in its _expression_. |
| 136 | +
|
| 137 | +> Examples of invalid messages resulting in a _Duplicate Declaration_ error: |
| 138 | +> |
| 139 | +> ``` |
| 140 | +> .input {$var :number maxFractionDigits=0} |
| 141 | +> .input {$var :number minFractionDigits=0} |
| 142 | +> {{Redeclaration of the same variable}} |
| 143 | +> |
| 144 | +> .local $var = {$ext :number maxFractionDigits=0} |
| 145 | +> .input {$var :number minFractionDigits=0} |
| 146 | +> {{Redeclaration of a local variable}} |
| 147 | +> |
| 148 | +> .input {$var :number minFractionDigits=0} |
| 149 | +> .local $var = {$ext :number maxFractionDigits=0} |
| 150 | +> {{Redeclaration of an input variable}} |
| 151 | +> |
| 152 | +> .local $var = {$ext :someFunction} |
| 153 | +> .local $var = {$error} |
| 154 | +> .local $var2 = {$var2 :error} |
| 155 | +> {{{$var} cannot be redefined. {$var2} cannot refer to itself}} |
| 156 | +> ``` |
| 157 | +
|
| 158 | +### Duplicate Option Name |
| 159 | +
|
| 160 | +A **_<dfn>Duplicate Option Name</dfn>_** error occurs when the same _identifier_ |
| 161 | +appears on the left-hand side of more than one _option_ in the same _expression_. |
| 162 | +
|
| 163 | +> Examples of invalid messages resulting in a _Duplicate Option Name_ error: |
| 164 | +> |
| 165 | +> ``` |
| 166 | +> Value is {42 :number style=percent style=decimal} |
| 167 | +> ``` |
| 168 | +> |
| 169 | +> ``` |
| 170 | +> .local $foo = {horse :func one=1 two=2 one=1} |
| 171 | +> {{This is {$foo}}} |
| 172 | +> ``` |
| 173 | +
|
| 174 | +## Resolution Errors |
| 175 | +
|
| 176 | +**_<dfn>Resolution Errors</dfn>_** occur when the runtime value of a part of a message |
| 177 | +cannot be determined. |
| 178 | +
|
| 179 | +### Unresolved Variable |
| 180 | +
|
| 181 | +An **_<dfn>Unresolved Variable</dfn>_** error occurs when a variable reference cannot be resolved. |
| 182 | +
|
| 183 | +> For example, attempting to format either of the following messages |
| 184 | +> would result in an _Unresolved Variable_ error if done within a context that |
| 185 | +> does not provide for the variable reference `$var` to be successfully resolved: |
| 186 | +> |
| 187 | +> ``` |
| 188 | +> The value is {$var}. |
| 189 | +> ``` |
| 190 | +> |
| 191 | +> ``` |
| 192 | +> .match {$var :func} |
| 193 | +> 1 {{The value is one.}} |
| 194 | +> * {{The value is not one.}} |
| 195 | +> ``` |
| 196 | +
|
| 197 | +### Unknown Function |
| 198 | +
|
| 199 | +An **_<dfn>Unknown Function</dfn>_** error occurs when an _expression_ includes |
| 200 | +a reference to a function which cannot be resolved. |
| 201 | +
|
| 202 | +> For example, attempting to format either of the following messages |
| 203 | +> would result in an _Unknown Function_ error if done within a context that |
| 204 | +> does not provide for the function `:func` to be successfully resolved: |
| 205 | +> |
| 206 | +> ``` |
| 207 | +> The value is {horse :func}. |
| 208 | +> ``` |
| 209 | +> |
| 210 | +> ``` |
| 211 | +> .match {|horse| :func} |
| 212 | +> 1 {{The value is one.}} |
| 213 | +> * {{The value is not one.}} |
| 214 | +> ``` |
| 215 | +
|
| 216 | +### Unsupported Expression |
| 217 | +
|
| 218 | +An **_<dfn>Unsupported Expression</dfn>_** error occurs when an expression uses |
| 219 | +syntax reserved for future standardization, |
| 220 | +or for private implementation use that is not supported by the current implementation. |
| 221 | +
|
| 222 | +> For example, attempting to format this message |
| 223 | +> would always result in an _Unsupported Expression_ error: |
| 224 | +> |
| 225 | +> ``` |
| 226 | +> The value is {@horse}. |
| 227 | +> ``` |
| 228 | +> |
| 229 | +> Attempting to format this message would result in an _Unsupported Expression_ error |
| 230 | +> if done within a context that does not support the `^` private use sigil: |
| 231 | +> |
| 232 | +> ``` |
| 233 | +> .match {|horse| ^private} |
| 234 | +> 1 {{The value is one.}} |
| 235 | +> * {{The value is not one.}} |
| 236 | +> ``` |
| 237 | +
|
| 238 | +### Unsupported Statement |
| 239 | +
|
| 240 | +An **_<dfn>Unsupported Statement</dfn>_** error occurs when a message includes a _reserved statement_. |
| 241 | +
|
| 242 | +> For example, attempting to format this message |
| 243 | +> would always result in an _Unsupported Statement_ error: |
| 244 | +> |
| 245 | +> ``` |
| 246 | +> .some {|horse|} |
| 247 | +> {{The message body}} |
| 248 | +> ``` |
| 249 | +
|
| 250 | +## Selection Errors |
| 251 | +
|
| 252 | +**_<dfn>Selection Errors</dfn>_** occur when message selection fails. |
| 253 | +
|
| 254 | +> For example, attempting to format either of the following messages |
| 255 | +> might result in a _Selection Error_ if done within a context that |
| 256 | +> uses a `:plural` selector function which requires its input to be numeric: |
| 257 | +> |
| 258 | +> ``` |
| 259 | +> .match {|horse| :plural} |
| 260 | +> 1 {{The value is one.}} |
| 261 | +> * {{The value is not one.}} |
| 262 | +> ``` |
| 263 | +> |
| 264 | +> ``` |
| 265 | +> .local $sel = {|horse| :plural} |
| 266 | +> .match {$sel} |
| 267 | +> 1 {{The value is one.}} |
| 268 | +> * {{The value is not one.}} |
| 269 | +> ``` |
| 270 | +
|
| 271 | +## Formatting Errors |
| 272 | +
|
| 273 | +**_<dfn>Formatting Errors</dfn>_** occur during the formatting of a resolved value, |
| 274 | +for example when encountering a value with an unsupported type |
| 275 | +or an internally inconsistent set of options. |
| 276 | +
|
| 277 | +> For example, attempting to format any of the following messages |
| 278 | +> might result in a _Formatting Error_ if done within a context that |
| 279 | +> |
| 280 | +> 1. provides for the variable reference `$user` to resolve to |
| 281 | +> an object `{ name: 'Kat', id: 1234 }`, |
| 282 | +> 2. provides for the variable reference `$field` to resolve to |
| 283 | +> a string `'address'`, and |
| 284 | +> 3. uses a `:get` formatting function which requires its argument to be an object and |
| 285 | +> an option `field` to be provided with a string value, |
| 286 | +> |
| 287 | +> ``` |
| 288 | +> Hello, {horse :get field=name}! |
| 289 | +> ``` |
| 290 | +> |
| 291 | +> ``` |
| 292 | +> Hello, {$user :get}! |
| 293 | +> ``` |
| 294 | +> |
| 295 | +> ``` |
| 296 | +> .local $id = {$user :get field=id} |
| 297 | +> {{Hello, {$id :get field=name}!}} |
| 298 | +> ``` |
| 299 | +> |
| 300 | +> ``` |
| 301 | +> Your {$field} is {$id :get field=$field} |
| 302 | +> ``` |
0 commit comments