Repository navigation
Description
Which @angular/* package(s) are relevant/related to the feature request?
core, common
Description
I'd like to suggest a change to resources before they get stabilized. This suggestion is heavily inspired by Rust's Result<T, E> type and a little bit by the libraries neverthrow and effect. The idea is to make errors not be second-class citizens, make them become just another value that is there when an error happened.
Currently, errors in resources are typed to just be instances of Error. As a result, when you use an error in a template or just simply in a component, you have to do dirty tricks if you want to work in a type-safe way with errors. As a result, error handling often becomes more cumbersome and is more likely to be neglected.
We use resources extensively since their introduction and the ergonomics are great when it comes to the happy path. However, in our application, error handling is often more complex than the success case. There are often many many more things to do when errors occur.
I realise that these suggestions are opinionated and go against what we've been used to from RXJS and Promise APIs, but there have been other libraries gaining popularity that also do this. I do also realise that TypeScript doesn't really help (typing when throwing isn't type checked, etc.), but this would be opt-in anyway, so I don't see how it would be harmful.
Proposed solution
Feature request 0: Resource<T, E extends Error = Error>
This suggestion is sort of a pre-requesit to other suggestions.
This first suggestion is to add a second optional generic type to resources as well as all their implementations and a new method hasError() that works similarly to hasValue().
interface Resource<T, E extends Error = Error> {
...
readonly error: Signal<E | undefined>;
hasError(): this is Resource<T, Exclude<E, undefined>>;
}Feature request 1: Resource<T, E>
I personally fail to see the point of requring errors to be instances of Error, especially in the context of strong error typing.
As an example Rust's Result<T, E> doesn't enforce any specific restrictions on E, which makes it much more versatile.
Currently, if you throw an error that's not an instance of Error, it gets encapsulated into one. If one might argue that promises don't have error types in their signature, they do allow you to throw with anyhing, not just Errors.
Feature request 2: setError(error: E) and update(updater: (value: E) => E): void; on WritableResource<T, E>
Feature request 3: setError(error: E) and update(updater: (value: E) => E): void; on WritableResource<T, E>
Feature request 4: Add parseError() to HttpResourceOptions.
This would allow to be able to shape errors that one would get from an API. This would also have the advantage of being able to enforce type safety on the return error values.
Alternatives considered
Make custom wrappers around resource APIs in userland that do this instead, but this would make things complicated.
Activity
[-]Strong error typing on `Resource` and `HttpResource` signatures[/-][+]Feature Request: Strong error typing on `Resource` and `HttpResource` signatures[/+]sysmat commentedon Sep 2, 2025