Learn / Errors and failures

Signed out

A request whose session ended answers 401 with Your session ended.; a read reads Failed, and a write is listed failed, with _tag: 'Unauthenticated'. RemoteData.denied(error) reads either as a typed Denied:

ts
import { Option } from 'effect'
import { Denied, RemoteData, type RemoteError } from 'foldkit-remote'

const failure = (error: RemoteError): string =>
  Option.match(RemoteData.denied(error), {
    onNone: () => `Could not load: ${error.message}`,
    onSome: Denied.match({
      Unauthenticated: () => 'Your session ended. Sign in again.',
      Forbidden: () => 'You may not read this.',
    }),
  })

Asking again as the same caller is refused again, so show it rather than retry. When the signed-in person changes, Data.forget(model) drops every server-derived fact, failures and failed writes included. A live stream refused this way restarts on its backoff like any break, and is refused until the page has a session again. See Refusals and Who the client believes it is.

Lazy resources

A service whose code loads on first use (Resource.lazy) fails its Resource.get with LoadError (_tag: 'ResourceLoadError') when the import fails, a dropped connection for instance. The failed load is forgotten, so the next get imports again: handle it in the Command, and a later ask retries.

ts
import { Context, Effect } from 'effect'
import { Resource } from 'foldkit-bundle'

class Charts extends Context.Service<Charts, { readonly draw: Effect.Effect<void> }>()('Charts') {}

const drawn = Resource.get(Charts).pipe(
  Effect.flatMap(charts => charts.draw),
  Effect.catchTag('ResourceLoadError', () => Effect.succeed('not loaded')),
)