Skip to content

Operation scopes ​

A scope carries metadata for one unit of work. It is a plain value, not a global, so two operations running at the same time can never see each other's data.

ts
const upload = flare.scope({
  operation: "upload-avatar",
  tags: { area: "upload" },
  contexts: { file: { size: 48_213, type: "image/png" } },
});

try {
  await uploadAvatar();
} catch (error) {
  upload.capture(error);
}

upload.message("Upload was slow", { level: "warning" });

A scope has capture and message, with the same options as the ones on the Flare. Options given at the call win over the scope's, which win over the session's.

What a scope does not do ​

  • It does not collect. There is no scope.tag() or scope.breadcrumb(). A scope is fixed when it is created. If the work needs different metadata, create another scope.
  • It does not nest. There is no parent. Combine options yourself when you need to.
  • It does not end. There is nothing to close and nothing to leak, so you can create one per request, per upload or per screen.
  • It does not propagate. Flare never uses async context or a global stack to find a scope. You pass the scope to the code that needs it, which is the only approach that behaves the same in browsers, in React Native and on a server.

Scopes and accounts ​

A scope belongs to the identity it was created under. After the user changes, every capture through that scope is dropped with the reason stale-scope. See users and account switching.

Scopes on a server ​

On a server, one Flare serves many requests, so session data such as flare.user() is the wrong tool: it would be shared by every request. Use a scope per request and pass the user in it:

ts
const handleRequest = async (request: Request, userId: string) => {
  const scope = flare.scope({
    operation: `${request.method} ${new URL(request.url).pathname}`,
    user: { id: userId },
  });

  try {
    return await respond(request);
  } catch (error) {
    scope.capture(error);

    return new Response("Internal error", { status: 500 });
  }
};

See server rendering.

Released under the MIT License.