question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Error messages should place most relevant information first.

See original GitHub issue

Here’s an actual example of an error message that can go wrong in our library when mispelling a property when creating an object literal:

[ts]
Type '{ containers: { nginx: { image: string; memory: number; portMappings: NetworkListener[]; enviroment: number; }; }; }' is not assignable to type 'FargateTaskDefinitionArgs'.
  Types of property 'containers' are incompatible.
    Type '{ nginx: { image: string; memory: number; portMappings: NetworkListener[]; enviroment: number; }; }' is not assignable to type 'Record<string, Container>'.
      Property 'nginx' is incompatible with index signature.
        Type '{ image: string; memory: number; portMappings: NetworkListener[]; enviroment: number; }' is not assignable to type 'Container'.
          Object literal may only specify known properties, but 'enviroment' does not exist in
          type 'Container'. Did you mean to write 'environment'? [2322]

- fargateService.d.ts(169, 5): The expected type comes from property 'taskDefinitionArgs'
  which is declared here on type 'FargateServiceArgs'

The funny thing here is that the final parts of the error message are superb. Namely:

- Object literal may only specify known properties, but 'enviroment' does not exist in
  type 'Container'. Did you mean to write 'environment'? [2322]

- fargateService.d.ts(169, 5): The expected type comes from property 'taskDefinitionArgs'
  which is declared here on type 'FargateServiceArgs'

However, the actual output is quite cluttered and hard to glean the information from. This is esp. true in an ide setting where one sees something like this:

image

This view is particularly problematic due to the wrapping and wall-of-goop nature of this type of error.

My suggestion would be to invert the information being provided by errors. Give the most specific and directly impactful information first (i.e. Object literal may only specify known properties, but 'enviroment' does not exist in type 'Container'. Did you mean to write 'environment'?), and then follow that up with all the extra details that can be used to dive deeper into things when that isn’t clear enough.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:26
  • Comments:22 (22 by maintainers)

github_iconTop GitHub Comments

6reactions
RyanCavanaughcommented, Feb 5, 2019

Sometimes inside-out is the best error, sometimes outside-in is the best error. It depends on whether your error is because the type “isn’t even close” (i.e. you have the completely wrong kind of object), or if there’s something “subtly wrong” (i.e. you are off by one property spelling or type).

Consider this code:

// Library code
type Flippy<T> = T extends string ? number : object;
class Alpha<T> {
    getBar() {
        return {
            doSomething() {
                return {
                    another: null as Flippy<T>
                }
            }
        }
    }
}

class Beta<T> {
    getBar() {
        return {
            doSomething() {
                return {
                    another: null as Flippy<T>
                }
            }
        }
    }
}

// User code
const a: Alpha<string> = new Beta<boolean>();

The error message here is:

sample.ts:26:7 - error TS2322: Type 'Beta<boolean>' is not assignable to type 'Alpha<string>'.
  Types of property 'getBar' are incompatible.
    Type '() => { doSomething(): { another: object; }; }' is not assignable to type '() => { doSomething(): { another: number; }; }'.
      Type '{ doSomething(): { another: object; }; }' is not assignable to type '{ doSomething(): { another: number; }; }'.
        Types of property 'doSomething' are incompatible.
          Type '() => { another: object; }' is not assignable to type '() => { another: number; }'.
            Type '{ another: object; }' is not assignable to type '{ another: number; }'.
              Types of property 'another' are incompatible.
                Type 'object' is not assignable to type 'number'.

The last 7 lines of that error message are not really relevant (it’s not really the error the developer is making, just an explanation of why the assignment is an error), and arguably only the first line is needed for the user to know what’s gone wrong.

Displaying the inner message first here looks like TS has lost its mind:

const a: Alpha<string> = new Beta<boolean>();
// Type 'object' is not assignable to type 'number'.
2reactions
CyrusNajmabadicommented, Feb 5, 2019

Hurrdurr. Me smart. Me also on 3.2.2

Where are you now? Our current office is downtown 😄

Read more comments on GitHub >

github_iconTop Results From Across the Web

The Best Place for Error Messages on Forms - UX Movement
Both to the right of the field and below the field are optimal locations for error messages. But which placement should you use?...
Read more >
How to Write Good Error Messages - UX Planet
Error message should contain necessary information. Most of the time user is not willing to read a long story. Be concise and write...
Read more >
Error Messages: Examples, Best Practices & Common Mistakes
Useful error messages can keep users on your site and increase conversions. See examples and learn the best practices.
Read more >
Error Message Guidelines - Nielsen Norman Group
Of course, error messages should be brief and to the point, as should all Web content. However, error messages can still teach users...
Read more >
How to Write Good Error Messages - UX Design World
The error message should contain the necessary information. Most of the time user is not willing to read a long story.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found