Skip to content

Require schemas for non-default activity success and error types - #8

Open
sundaray wants to merge 1 commit into
TeamSpringbird:mainfrom
sundaray:fix/activity-schema-requirements
Open

sundaray wants to merge 1 commit into
TeamSpringbird:mainfrom
sundaray:fix/activity-schema-requirements

Conversation

@sundaray

Copy link
Copy Markdown
Contributor

Issue

Here is an example of an activity that creates an evaluation record:

import { Schema } from "effect";
import { defineActivity } from "@springbird/effect-temporal/definition";

const EvaluationCreationRejected = Schema.TaggedStruct(
  "EvaluationCreationRejected",
  {
    evaluationId: Schema.String,
    reason: Schema.String,
  },
);

type CreateEvaluationPayload = {
  evaluationId: typeof Schema.String;
  participantId: typeof Schema.String;
  reviewerId: typeof Schema.String;
};

const CreateEvaluationRecord = defineActivity<
  "createEvaluationRecord",
  CreateEvaluationPayload,
  typeof Schema.String,
  typeof EvaluationCreationRejected
>("createEvaluationRecord", {
  payload: {
    evaluationId: Schema.String,
    participantId: Schema.String,
    reviewerId: Schema.String,
  },

  error: EvaluationCreationRejected,

  options: {
    startToCloseTimeout: "10 seconds",
    retry: {
      maximumAttempts: 3,
    },
  },
});

Notice that I have explicitly provided typeof Schema.String as the third generic argument.

This tells TypeScript that the activity's successful result is a string. However, I haven't provided the the corresponding runtime schema.

TypeScript currently accepts this declaration without reporting an error. This happens because success and error are always optional in the defineActivity declaration:

decl: {
  readonly payload: Payload;
  readonly success?: Success;
  readonly error?: Error;
  readonly options?: TypedActivityOptions;
}

The same optional properties are also accepted by the internal makeTypedActivity helper. When a schema is omitted, makeTypedActivity falls back to Schema.Void or Schema.Never:

successSchema: (definition.success ?? Schema.Void) as Success,
errorSchema: (definition.error ?? Schema.Never) as Error,

This allows the generic type and runtime schema to disagree.

In the example above:

  • TypeScript treats the activity's successful result as a string.
  • The runtime uses Schema.Void because success was omitted.

The same mismatch is possible when a non-default Error generic is provided but its corresponding error schema is
omitted.

Solution

This change makes the optionality of success and error depend on the generic types supplied to defineActivity:

  • success remains optional when Success is the default Schema.Void.
  • error remains optional when Error is the default Schema.Never.
  • A non-default Success generic requires a corresponding success schema.
  • A non-default Error generic requires a corresponding error schema.

Normal inferred declarations continue to work.

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

Successfully merging this pull request may close these issues.

1 participant