Skip to content

fixed outcome issue when subclassing FlowSendHttpRequest #7407#7425

Open
minaxi98 wants to merge 2 commits into
elsa-workflows:mainfrom
minaxi98:bugfix-7407
Open

fixed outcome issue when subclassing FlowSendHttpRequest #7407#7425
minaxi98 wants to merge 2 commits into
elsa-workflows:mainfrom
minaxi98:bugfix-7407

Conversation

@minaxi98
Copy link
Copy Markdown
Contributor

@minaxi98 minaxi98 commented Apr 26, 2026

Purpose

Fixes subclasses of FlowSendHttpRequest showing only the "Done" outcome in the Studio designer by declaring flow ports on the base class so they are inherited automatically.

Scope

Select one primary concern:

  • Bug fix (behavior change)
  • Refactor (no behavior change)
  • Documentation update
  • Formatting / code cleanup
  • Dependency / build update
  • New feature

If this PR includes multiple unrelated concerns, please split it before requesting review.


Description

Problem

When subclassing FlowSendHttpRequest (e.g. class MyFlowSendHttpRequest : FlowSendHttpRequest), the Elsa Studio designer only showed a single "Done" outcome port. The expected ports — "Done", "Unmatched status code", "Failed to connect", "Timeout", and the configured status-code ports (e.g. "200") — were all missing.

The root cause is that FlowSendHttpRequest had no [FlowNode] attribute. ActivityDescriber.DescribeActivityAsync uses GetCustomAttribute(inherit: true) to build the Ports collection in the activity descriptor. Without the attribute on the base class, every subclass registered under its own type name received zero flow ports. The Studio hardcodes "Done" as a fallback, which is why only that one outcome appeared.

Solution

Solution
Added [FlowNode("Done", "Unmatched status code", "Failed to connect", "Timeout")] to FlowSendHttpRequest. Because FlowNodeAttribute has Inherited = true (the default) and ActivityDescriber calls GetCustomAttribute with inherit: true, all subclasses automatically inherit these ports without needing to redeclare the attribute.

Added FlowSendHttpRequestDescriptorModifier (IActivityDescriptorModifier) that detects any type assignable to FlowSendHttpRequest and appends flow ports for each status code present in the ExpectedStatusCodes input's default value. This ensures the default "200" port (and any other default codes a subclass declares) is visible at design time.

Registered the modifier in both HttpFeature and ShellFeatures/HttpFeature.

Verification

Steps:

Create a subclass of FlowSendHttpRequest in your project: public class MyFlowSendHttpRequest : FlowSendHttpRequest { }
Register it and open Elsa Studio.
Add the custom activity to a Flowchart workflow.
Expected outcome: The activity node shows "Done", "Unmatched status code", "Failed to connect", "Timeout", and "200" outcome ports — identical to the built-in FlowSendHttpRequest.

Screenshots / Recordings (if applicable)


Commit Convention

We recommend using conventional commit prefixes:

  • fix: – Bug fixes (behavior change)
  • feat: – New features
  • refactor: – Code changes without behavior change
  • docs: – Documentation updates
  • chore: – Maintenance, tooling, or dependency updates
  • test: – Test additions or modifications

Clear commit messages make reviews easier and history more meaningful.


Checklist

  • The PR is focused on a single concern
  • Commit messages follow the recommended convention
  • Tests added or updated (if applicable)
  • Documentation updated (if applicable)
  • No unrelated cleanup included
  • All tests pass

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 26, 2026

Greptile Summary

This PR fixes the missing outcome ports for subclasses of FlowSendHttpRequest (#7407) by adding a [FlowNode] attribute to the base class and a new FlowSendHttpRequestDescriptorModifier that dynamically appends status-code ports from the ExpectedStatusCodes default value. Both the main and shell HttpFeature registrations are updated, and unit tests cover the key scenarios cleanly.

One design consideration worth noting: subclasses that wish to advertise different default status codes at design time would need to re-declare ExpectedStatusCodes with a custom DefaultValueProvider = typeof(MySubclass) in their own [Input] attribute, because the inherited attribute still points to typeof(FlowSendHttpRequest) as its provider. This is a pre-existing limitation of Elsa's IActivityPropertyDefaultValueProvider pattern, not introduced by this PR.

Confidence Score: 5/5

This PR is safe to merge; the fix is narrowly scoped, correct, and well-covered by unit tests.

No P0 or P1 issues found. Changes are additive (a new attribute, a new modifier, two DI registrations) and the existing ActivityDescriptor.Ports list is properly initialized so null-reference risk is absent. The FlowNodeAttribute inheritance model is correct and the duplicate-port guard in the modifier prevents double-registration.

No files require special attention.

Important Files Changed

Filename Overview
src/modules/Elsa.Http/Activities/FlowSendHttpRequest.cs Adds [FlowNode] attribute to declare the four static outcome ports; the attribute is inheritable by default so subclasses pick it up automatically via GetCustomAttribute.
src/modules/Elsa.Http/Modifiers/FlowSendHttpRequestDescriptorModifier.cs New IActivityDescriptorModifier that appends flow ports for each int in the ExpectedStatusCodes input's DefaultValue; handles deduplication, type guard, and null default value correctly.
src/modules/Elsa.Http/Features/HttpFeature.cs Registers FlowSendHttpRequestDescriptorModifier as a scoped IActivityDescriptorModifier in the main workflow engine's DI container.
src/modules/Elsa.Http/ShellFeatures/HttpFeature.cs Registers the same modifier in the shell (Elsa Studio backend) DI container; mirrors the main HttpFeature registration as expected for this pattern.
test/unit/Elsa.Http.UnitTests/Activities/FlowSendHttpRequestTests.cs Comprehensive unit tests covering attribute inheritance, modifier port addition/deduplication, null/missing default value guards, and unrelated activity no-op; good regression coverage for #7407.

Sequence Diagram

sequenceDiagram
    participant AS as ActivityDescriber
    participant FNA as FlowNodeAttribute<br/>(on FlowSendHttpRequest)
    participant AD as ActivityDescriptor
    participant MOD as FlowSendHttpRequestDescriptorModifier
    participant STUDIO as Elsa Studio

    AS->>FNA: GetCustomAttribute<FlowNodeAttribute>(inherit:true)
    FNA-->>AS: ["Done","Unmatched status code","Failed to connect","Timeout"]
    AS->>AD: Populate Ports (static flow ports)
    AS->>AD: Populate Inputs (incl. ExpectedStatusCodes DefaultValue=[200])
    AS->>MOD: Modify(descriptor)
    MOD->>AD: ClrType.IsAssignableTo(FlowSendHttpRequest)?
    AD-->>MOD: true (base or subclass)
    MOD->>AD: Read ExpectedStatusCodes.DefaultValue
    AD-->>MOD: [200]
    MOD->>AD: Append Port("200", PortType.Flow)
    AD-->>STUDIO: Descriptor with ports: Done, Unmatched status code, Failed to connect, Timeout, 200
Loading

Reviews (2): Last reviewed commit: "Update src/modules/Elsa.Http/Modifiers/F..." | Re-trigger Greptile

Comment thread src/modules/Elsa.Http/Modifiers/FlowSendHttpRequestDescriptorModifier.cs Outdated
…odifier.cs

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
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