Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Error handling / Recovery approach in reactive chains (cells) #111

Open
lifeart opened this issue Aug 2, 2023 · 2 comments
Open

Comments

@lifeart
Copy link

lifeart commented Aug 2, 2023

Hi there! I have relatively generic / documentation related question about sync (syntax, non existing objects / etc) errors handing in starbeam.

According to current flow in glimmer-vm tracking/rendering errors seems unrecoverable (if we have render error - application should be reloaded)

I do understand that this repo not related to DOM rendering, but it will be really great to get understanding on error flow here. Especially, error strategies.

For example:

  • Error in resource (is dependent resources / cells gonna break?)
  • Error in resource chain (is next, not related resources still executable?)
  • Error in cell (will it break resource / whole calculation / recalculation chain)

Also, I'm interested in desired error-recovery approaches if applicable:

For example:

  • Last non-errored value returned
  • Break the world
  • Break chain
  • Default value returned / etc
@lifeart
Copy link
Author

lifeart commented Aug 2, 2023

It seems in modern web applications state / computation error should not break app (especially, for apps written by beginners).

I would like to see "safe" coding approaches here as well as "strict".

Since our apps is now component based, it seems fine to have "broken" component if something "bad" happens, instead of broken app.

It's really hard to cover all logic on 100% by tests in real life-applications. In addition, if we use 3rd party libs in "tracked" chains, it may literally be broken on random moment (if it's dynamically injected, for example). And it will be great to have safe approach here.. (I do understand it adds more resource usage, but, may save bunch of jobs / nerves).

@NullVoxPopuli
Copy link
Contributor

This reminds me of https://fsharpforfunandprofit.com/rop/ which is in user space (Rust and Go have this concept, too), but I think we can do similar in JavaScript.

for error handling / error-recovery, I feel like this should be a rendering framework level concept, like, React and Vue have ErrorBoundaries, Svelte has literal try/catch blocks in templates, etc.

Atm, none of the examples provided are unique to Starbeam, but I think we could provide learning materials as well as a low level API for handling errors, -- but more importantly, teach approaches to better help handle errors.

For example, right now, cells, resources, etc in Starbeam have a .current property to get the current value. If we were to add an .error property, we'd need to make sure that we never swallow errors and still print them out. I don't think it'd be possible to have an upstream resource be in an error state and still be able to be consumed by other resources though (or eventually the rendering framework) -- someone has to handle the error -- it's just that the current approach is to handle it as upstream as possible, in userland.

As far as primitives go, I think this would be very hard. but! I think it's possible to provide utility wrappers around untrusted functions that could provide some state.
For example:

import { Resource } from '@starbeam/universal';
import { Maybe } from 'some-utility-library';

const MyResource = Resource(({ use }) => {
  const result = use(Maybe(() => /* the dangerous task */));

  // forwarding ok/error state to consumers of MyResource
  return {
    get ok() {
      return result.current.ok;
    },
    get error() {
      return result.current.error;
    }
  }
});

It may also be possible to have this handle resources as well

import { Resource } from '@starbeam/universal';
import { Maybe } from 'some-utility-library';
import { SomeOtherResource } from './somewhere';

const MyResource = Resource(({ use }) => {
  const result = use(Maybe(() => use(SomeOtherResource));

  // forwarding ok/error state to consumers of MyResource
  return {
    get ok() {
      return result.current.ok;
    },
    get error() {
      return result.current.error;
    }
  }
});

idk, will need to think on this some more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants