# RFC: Revamp how compile time errors are shown

**URL:** <https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548>\
**Category:** Crystal Contrib\
**Created:** [March 15, 2019, 2:21am UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548 "2019-03-15T02:21:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![paulcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/paulcsmith/32/301_2.png) [@paulcsmith](https://forum.crystal-lang.org/u/paulcsmith)\
**Post date:** [March 15, 2019, 2:21am UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/1 "2019-03-15T02:21:33Z")

</div>

## The Problem

Right now some errors can be unwieldy to read for a few reasons

- It shows all frames. This can lead to pages of text that looks overwhelming and makes it hard to the error.
- It is not always clear what the error is or where it is located

## The Proposed Changes

- By default, just show the code with the error, not the entire stack trace. This is what Elm does and it works quite well. Helps focus on what is necessary
- Add a command line option and/or ENV to show the full trace. Sometimes it is useful to see more, but let’s make that optional instead of making the current verbose output the default. Example ``
- Some changes to how the error is displayed to make it easier to scan at a glance. Code + pics attached

## Example Code and Screenshots

> **[paulcsmith/crystal-errors](https://github.com/paulcsmith/crystal-errors)**
>
> Contribute to paulcsmith/crystal-errors development by creating an account on GitHub.

## Implementation Details

### For errors without more info (just one line)

- Prefix with “Error”
- Print error message in yellow and bold
- (not sure about this) show how to print the full trace (like it does now)
- Show what file it is
- Show line number right by the source code line
- Show code line (maybe bolded?)

> <https://github.com/paulcsmith/crystal-errors/blob/master/errors/type_restriction.cr>

 ![07%20PM](https://canada1.discourse-cdn.com/flex036/uploads/crystal_lang/original/1X/9bcbd146ef0aa58893005bd7db8bcd65f7679bcc.png)

**More screenshots at** [https://github.com/paulcsmith/crystal-errors](https://github.com/paulcsmith/crystal-errors)

### For errors with more than one line

- Print first line in yellow just like other errors
- Everything after first newline goes after the source line.

> <https://github.com/paulcsmith/crystal-errors/blob/master/errors/no_overload.cr>

### Macro errors

- Print surrounding lines
- Only bold line with the problem
- Show the expanded code, and underneath it show the unexpanded code

It is important to show both. The unexpanded part show what the user wrote. The expanded part helps figure out why the issue might be there. Use --verbose/–debug for more in-depth look if it still is not enough

> <https://github.com/paulcsmith/crystal-errors/blob/master/errors/macro_error.cr>

### Not Sure About

- Not sure about including the dim line that says how to show full trace. Maybe not useful enough?
- Should source code line be bolded? Maybe too much is going on.

## Who would do this work?

I wish I had more time for this, but with all the stuff with Lucky I just don’t have time. I’m happy to help where I can but I likely won’t be able to help with code.

I _really_ want this feature though and will open up a Bounty Hunt to help out if this gets approved :D

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [March 15, 2019, 12:34pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/2 "2019-03-15T12:34:32Z")

</div>

I recently started to code in Elm and I love the error messages. They look like a human is talking to you, not a machine. And I’d like Crystal to speak the same language.

That said, in Elm it’s easier. Everything is pretty much explicitly typed. There are no overloads. There’s no mutation of variables or automatic computation of unions. There are no macros. Etc., etc.

Still, we can improve our error messages. I just wonder if removing all the traces will make it harder to understand what’s going on, but we can try it.

I can work on this, though my time to do it is also pretty tight. But given that I wrote most of the code for errors it’ll be easier for me to do it.

I like the name `--verbose`, though right now it’s taken and use to display the linker command. We can probably rename that (the existing flag) to something else.

Then, instead of “type must be String, not Int32”, which looks robotic, I’d like to see it more Elm-ish, like “You told me `foo` returned String but it seems to be returning Int32”, and so on. Instead of “undefined constant Foo” maybe “I can’t find a type or constant named ‘Foo’”. Instead of “undefined method ‘not\_a\_method’ for String” maybe “I can’t find an instance method ‘not\_a\_method’ defined in String”. And so on.

What do you think?

If we do this, I’ll start improving the lexer (syntax) errors first.

---

<div class="post-metadata">

**Author:** ![paulcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/paulcsmith/32/301_2.png) [@paulcsmith](https://forum.crystal-lang.org/u/paulcsmith)\
**Post date:** [March 15, 2019, 1:17pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/3 "2019-03-15T13:17:28Z")

</div>

## Improving messaging

Yes! I would love Crystal to have more Elm like error message, and I love your idea to make it more human like.

Your examples are awesome. I personally prefer `"Crystal"` over `"I"`, e.g. `Crystal can't find the type or constant 'Foo'`

I think improving syntax errors would be great too. I’d love to help with that if you need it

## CLI Flag --verbose

As for the flag, maybe instead of `--verbose` `--all-frames` or `--full-trace`? I also think an ENV var might be nice too.

## Not enough info with last frame

If we find that the last it is not enough information most of the time, I can work on a design that still puts emphasis on the last frame so it is clear that’s the main one to look at. Right now they all look the same so it can make it tricky to find what part is the problem

My initial though is keep the error message yellow and add some kind of delineation around it: `-- Error: Some error --`

## Future ideas

I also had ideas on how to improve the overloads errors, but I wanted to focus mostly on the design and information overload. I’d love to help where I can though. Please feel free to ping me on any PRs if you need/want some design or language input!

---

<div class="post-metadata">

**Author:** ![paulcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/paulcsmith/32/301_2.png) [@paulcsmith](https://forum.crystal-lang.org/u/paulcsmith)\
**Post date:** [March 15, 2019, 1:26pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/4 "2019-03-15T13:26:49Z")

</div>

Would it be ok to move this to an issue on Crystal-lang with a draft plan of action? Then I can add a bounty on bounty source. I am _really_ excited to have improved error messages :D

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [March 15, 2019, 1:48pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/5 "2019-03-15T13:48:28Z")

</div>

> [@paulcsmith](#):
>
> Your examples are awesome. I personally prefer `"Crystal"` over `"I"` , e.g. `Crystal can't find the type or constant 'Foo'`

In the end, is crystal who is speaking so it’s like itself talking in 3rd singular. There are some people that do that though. Another pro for `I` is that it’s the shorter it can get.

> [@paulcsmith](#):
>
> CLI Flag --verbose

`--trace-error` sounds like a good option for me. Like asking the compiler to trace the error.

> [@paulcsmith](#):
>
> Would it be ok to move this to an issue on Crystal-lang with a draft plan of action?

👍

---

<div class="post-metadata">

**Author:** ![paulcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/paulcsmith/32/301_2.png) [@paulcsmith](https://forum.crystal-lang.org/u/paulcsmith)\
**Post date:** [March 15, 2019, 2:27pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/6 "2019-03-15T14:27:10Z")

</div>

[https://github.com/crystal-lang/crystal/issues/7553](https://github.com/crystal-lang/crystal/issues/7553) with a bounty!  
[https://github.com/crystal-lang/crystal/issues/7554](https://github.com/crystal-lang/crystal/issues/7554)

---

<div class="post-metadata">

**Author:** ![z64](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/z64/32/34_2.png) [@z64](https://forum.crystal-lang.org/u/z64)\
**Post date:** [March 15, 2019, 3:07pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/7 "2019-03-15T15:07:22Z")

</div>

I’ve been exploring Rust a lot recently and one of the things I’m coming to love a lot is its error messages. I’ll take the example of a missing method:

`err.rs`

```auto
struct Foo { value: i32 }

fn main() {
  let foo = Foo { value: 1 };
  foo.bar();
}

```

Error with `rustc err.rs`:

```auto
error[E0599]: no method named `bar` found for type `Foo` in the current scope
 --> err.rs:5:9
  |
1 | struct Foo { value: i32 }
  | ---------- method `bar` not found for this
...
5 | foo.bar();
  | ^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

```

Compiler errors are given a code which you can then look up using `rustc` in your terminal, or browse them on the compiler error index, which showcases reproduceable examples of each error and suggestions on how to fix them:

[https://doc.rust-lang.org/error-index.html](https://doc.rust-lang.org/error-index.html)

Here’s a more complex example that I really like:

> <https://twitter.com/b0rk/status/954366146505052160>

I don’t suggest that we strive to implement exactly what Rust has, but I think there’s a lot to be inspired by - particularly I think the compiler error index and something like `rustc --explain`.

---

<div class="post-metadata">

**Author:** ![paulcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/paulcsmith/32/301_2.png) [@paulcsmith](https://forum.crystal-lang.org/u/paulcsmith)\
**Post date:** [March 15, 2019, 3:13pm UTC](https://forum.crystal-lang.org/t/rfc-revamp-how-compile-time-errors-are-shown/548/8 "2019-03-15T15:13:51Z")

</div>

Very cool. I find the formatting of Rust’s errors to be a bit overwhelming, but I do LOVE the `--explain` command. I also like the example you posted from Twitter that helps with the Syntax message. That kind of thing is super helpful
