--- title: "Error Message Reformat" tags: "schema" --- :::danger :boom: **Do Not Edit This Document** The work described in here is now living in: https://github.com/vmware-tanzu/carvel-ytt/issues/396 ::: # Error Message Reformat Inspired by: https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html General desired improvements: - more important information is in a more prominent place 1. what is the error? — the source line where the error likely occurred 2. what's wrong? — the exact expectation/invariant that was broken 3. where abouts? — roughly where about within the source file (i.e. line number) 4. where _exactly_? — the name of the file 5. how can I fix it? — hints of what to do next - make clear what's literal source and what's commentary. ## General Improvements - keep source line dead center (where the eye typically goes first) with even more surrounding whitespace - split filename and line number - reduce required eye movement to locate source line - makes output display more predictable (left-side is _always_ 8 characters wide) - use `=` in the gutter to indicate line is commentary, not source - bring description of actual and expected as just below the source line (where eye goes next) - ALL CAPS reads like yelling; instead pull error message to the top-line (relatively low prominence) to get proper separation from other data. - whitespace to separate "expectations" and "hints" - allow for multiple hints (e.g. split on `\n`?) to be able to provide more than one piece of advice without it getting too complicated. - use the verb "define" (instead of "declare") consistently throughout error messages. ## Scenarios - [Invalid Schema](#Invalid-Schema) - [Invalid Array Definition](#Invalid-Array-Definition) - [Mismatched Type](#MismatchediType) - [Undefined Map Key](#Undefined-Map-Key) ### Invalid Schema `null` provided as a value in Schema (which is both useless and likely a misguided attempt at making the default value `null` — when the author _should_ use `@schema/nullable`) **Before** ``` ytt: Error: values/00-values.yml:4 | system_domain: | | INVALID SCHEMA - null value is not allowed in schema (no type can be inferred from it) | (hint: to default to null, specify a value of the desired type and annotate with @schema/nullable) ``` **After** ``` ytt: Error: Invalid schema — null value not allowed here values/00-values.yml: | 4 | system_domain: | = found: null value = expected: non-null value = = hint: in YAML, omitting a value implies null. = hint: to set the default value to null, annotate with @schema/nullable. = hint: to allow any value, annotate with @schema/type any=True. ``` ### Invalid Array Definition **Before** ``` ytt: Error: values/00-values.yml:7 | app_domains: [] | | INVALID ARRAY DEFINITION IN SCHEMA - unable to determine the desired type | found: 0 array items | expected: exactly 1 array item, of the desired type | (hint: in a schema, the item of an array defines the type of its elements; its default value is an empty list) ``` **After** ``` ytt: Error: Invalid schema — wrong number of items in array definition values/00-values.yml: | 7 | app_domains: [] | = found: 0 array items = expected: exactly 1 array item, of the desired type = = hint: in schema, the one item of the array implies the type of its elements. = hint: in schema, the default value for an array is always an empty list. = hint: default values can be overriden via a data values overlay. ``` ### Mismatched Type ``` ytt: Error: Overlaying data values (in following order: values.yml): values.yml:3 | foo: "" | | TYPE MISMATCH - the value of this item is not what schema expected: | found: string | expected: integer (by schema.yml:3) ``` **After** ``` ytt: Error: Value is of wrong type values.yml: | 3 | foo: "" | = found: string = expected: integer (by schema.yml:3) ``` ### Undefined Map Key **Before** ``` ytt: Error: Overlaying data values (in following order: values/10-images.yml, values/20-secrets-config-values.yml, values/30-experimental-values.yml, cf-values.yml): values/10-images.yml:4 | images: | | UNEXPECTED KEY - the key of this item was not found in the schema's corresponding map: | found: images | expected: (a key defined in map) (by values/00-values.yml:2) | (hint: declare data values in schema and override them in a data values document) ``` **After** ``` ytt: Error: Overlaying data values (in following order: values/10-images.yml, values/20-secrets-config-values.yml, values/30-experimental-values.yml, cf-values.yml): Undefined key in map: values/10-images.yml: | 4 | images: | = found: images = expected: (a key from the map defined at values/00-values.yml:2) = = hint: is the key spelled correctly? = hint: to extend existing schema, define new keys in a schema overlay. ```