Skip to content

Make FunctionException a sealed class for v3 #1550

Description

@spydon

In #1545 the FunctionsFetchException, FunctionsRelayException, and FunctionsHttpException subtypes were added under FunctionException in a non-breaking way (plain inheritance), so existing catch (FunctionException) blocks keep working.

For v3 we should make FunctionException a sealed class so consumers get a compile-checked exhaustive switch over the failure mode:

try {
  await supabase.functions.invoke('hello');
} on FunctionException catch (error) {
  final message = switch (error) {
    FunctionsFetchException() => 'Network failure',
    FunctionsRelayException() => 'Relay error',
    FunctionsHttpException()  => 'Function returned ${error.status}',
  };
}

Why this is breaking (hence v3)

sealed implies abstract, so:

  • The public const FunctionException(...) constructor can no longer be used by external code to instantiate a bare FunctionException (e.g. in tests/mocks).
  • External packages can no longer extend or implement it.

A non-breaking intermediate sealed base does not help: as long as a bare FunctionException remains constructable, any switch must allow for one, so the three subtypes can never form the closed set the compiler checks for exhaustiveness. Real three-way exhaustiveness requires FunctionException itself to be sealed.

Where

  • packages/functions_client/lib/src/types.dart

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions