Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix(core): Ensure resource sets an error
Before this commit, a resource with a previous value wouldn't set the error state correctly.
This commit fixes this. A resource will set its status to error even when there was a previous valid value.
  • Loading branch information
JeanMeche committed Nov 24, 2024
commit e643d6d263cc015f27b0055d556432981d6b4a39
3 changes: 2 additions & 1 deletion packages/core/src/resource/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ abstract class BaseWritableResource<T> implements WritableResource<T> {
* Put the resource into the error state.
*/
protected setErrorState(err: unknown): void {
this.status.set(ResourceStatus.Error);
this.value.set(undefined);
// The previous line will set the status to `Local`, so we need to update it.
this.status.set(ResourceStatus.Error);
this.error.set(err);
}

Expand Down
35 changes: 35 additions & 0 deletions packages/core/test/resource/resource_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,45 @@ describe('resource', () => {

expect(echoResource.status()).toBe(ResourceStatus.Error);
expect(echoResource.isLoading()).toBeFalse();
expect(echoResource.hasValue()).toBeFalse();
expect(echoResource.value()).toEqual(undefined);
expect(echoResource.error()).toBe('Something went wrong....');
});

it('should expose errors on reload', async () => {
const backend = new MockEchoBackend();
const counter = signal(0);
const echoResource = resource({
request: () => ({counter: counter()}),
loader: (params) => {
if (params.request.counter % 2 === 0) {
return Promise.resolve('ok');
} else {
throw new Error('KO');
}
},
injector: TestBed.inject(Injector),
});

TestBed.flushEffects();
await backend.flush();

expect(echoResource.status()).toBe(ResourceStatus.Resolved);
expect(echoResource.isLoading()).toBeFalse();
expect(echoResource.hasValue()).toBeTrue();
expect(echoResource.value()).toEqual('ok');
expect(echoResource.error()).toBe(undefined);

counter.update((value) => value + 1);
TestBed.flushEffects();

expect(echoResource.status()).toBe(ResourceStatus.Error);
expect(echoResource.isLoading()).toBeFalse();
expect(echoResource.hasValue()).toBeFalse();
expect(echoResource.value()).toEqual(undefined);
expect(echoResource.error()).toEqual(Error('KO'));
});

it('should _not_ load if the request resolves to undefined', () => {
const counter = signal(0);
const backend = new MockEchoBackend();
Expand Down