# Error "detail"

**URL:** <https://es.discourse.group/t/error-detail/1857>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [December 5, 2023, 5:57pm UTC](https://es.discourse.group/t/error-detail/1857 "2023-12-05T17:57:46Z")\
**Posts on this page:** 1\
**Showing post:** 31

<div class="post-metadata">

**Author:** ![dmchurch](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/dmchurch/32/1962_2.png) [@dmchurch](https://es.discourse.group/u/dmchurch)\
**Post date:** [April 10, 2024, 7:24am UTC](https://es.discourse.group/t/error-detail/1857/31 "2024-04-10T07:24:33Z")

</div>

> [@theScottyJam](#):
>
> (You're right that I'm not _forced_ to use the error details proposal if it's provided, but I still care about it, because it feels like it's encouraging people to build not-as-nice error messages - and as a consumer of other people's error messages I care about how the language encourages them to be structured)

It's definitely a reasonable concern, you're not wrong at all - if you make a feature available, people will use it. And in this case in particular, it's worth remembering that not all environments _will_ understand or expect the `.details` property, and like you say, Errors should not become useless because, in the worst-case scenario, some framework causes all `Error.message`s to become `"An error was thrown by the application:"`. It's also a given that documentation is not a solution, we can't just say "let's tell people not to use `details` that way".

Put another way: right now, the lack of expressivity means _everyone_ is using `.message` to communicate whatever needs to be described about any given error, because that's the only option. The corollary to that is that an Error _consumer_ can be certain they've recorded whatever needs to be described just by storing the `.message` field.

So, if we want to make sure people don't abuse the details feature and, in so doing, break consumer expectations of the `.message` field, let's reduce its expressivity. My problem statement is that "Error should be as expressive as console.log", but this proposal currently goes further than that by expressing the details as an object with named fields.

So, **let's restrict the detail property to be arrays only.**

It still hasn't, technically, lost any expressivity, because you could just put an object with named fields as the single element of the details array, but that requires developer intent to break the standard. And that's fine, they should be _able_ to, but it shouldn't be the norm. Having details be an array also means that placeholders become much simpler - they can follow regex replacement placeholders and be $0, $1, etc.

But there's another thing that restricting it to arrays buys us, and I'll show rather than tell:

```javascript
const httpCode = 404, url = 'example.com';
throw Error.new`Received a ${httpCode} response while sending a request to ${url}`

// The Error.new() template function calls the following:

new Error("Received a $0 response while sending a request to $1", {
    detail: [httpCode, url],
});

// Which results in an Error object with the following properties:

{
    message: "Received a 404 response while sending a request to example.com",
    rawMessage: "Received a $0 response while sending a request to $1",
    detail: [404, "example.com"],
}

// and could be displayed in the same manner as:

console.error(
    "Received a ", httpCode, " response while sending a request to ", url);

```

I dunno about you but I _love_ that syntax. And, being a static method, `Error.new` is polymorphic to subclasses, so you can use any `MySpecializedError.new` in the same way.

The placeholder replacement only takes place for array indices that are valid to the length of the detail array, so if the array is length 0 or omitted, no placeholders are replaced and the `message` property will be the same as the `message` parameter passed to the constructor, regardless of if there are any `$0` sequences in the message.

If there are any valid placeholders, though, they will get replaced by the string coercion of that array value, the same as string templating and `String.raw` does. In that case, there will be a `rawMessage` property with the string passed as the `message` parameter to the constructor. I figure the Error prototype will have a `get rawMessage() { return this.message; }` getter defined, so that knowledgeable clients can always use it to get the raw value of the `message` property, whether placeholder replacement was performed or not.

What do you think? And, for that matter, @mmkal, what do you think about the reduction in scope of the feature, restricting the `detail` property to array values?

---

_[View the full topic](https://es.discourse.group/t/error-detail/1857)._
