Add status_from field to step.json_response for dynamic status codes#382
Add status_from field to step.json_response for dynamic status codes#382
Conversation
|
@copilot try again |
…odes Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> Agent-Logs-Url: https://github.com/GoCodeAlone/workflow/sessions/d57a0530-2320-4994-afe5-88b8d46b2a56
Done in commit 18f577d. The
|
There was a problem hiding this comment.
Pull request overview
Adds dynamic HTTP status support to step.json_response via a new status_from config field, allowing status codes to be resolved from pipeline context at runtime (e.g., proxying step.http_call’s status_code).
Changes:
- Add
status_fromparsing and runtime resolution instep.json_response. - Extend built-in step schema and documentation to mention
status_from. - Add unit tests covering common
status_frombehaviors and fallbacks.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
module/pipeline_step_json_response.go |
Implements status_from and resolves status at runtime before writing the response. |
schema/step_schema_builtins.go |
Adds status_from to the built-in schema for step.json_response. |
module/pipeline_step_json_response_test.go |
Adds tests for status_from behavior, precedence, and fallback scenarios. |
DOCUMENTATION.md |
Updates step.json_response entry to mention status_from. |
| if s.statusFrom != "" { | ||
| if val := resolveBodyFrom(s.statusFrom, pc); val != nil { | ||
| switch v := val.(type) { | ||
| case int: | ||
| return v | ||
| case float64: | ||
| return int(v) | ||
| case int64: | ||
| return int(v) | ||
| } |
There was a problem hiding this comment.
resolveStatus currently converts float64 (and int64) to int via a plain cast. This will silently truncate non-integer floats (e.g. 404.9 -> 404) and can allow out-of-range/invalid HTTP status codes to reach WriteHeader, which can cause runtime errors depending on the underlying ResponseWriter. Consider validating that the resolved value is an integer (no fractional part) and within the valid HTTP status code range before using it; otherwise fall back to the configured static status (or 200).
| func TestJSONResponseStep_StatusFromFloat64(t *testing.T) { | ||
| // JSON numbers are often decoded as float64; ensure conversion works. | ||
| factory := NewJSONResponseStepFactory() | ||
| step, err := factory("proxy-respond", map[string]any{ | ||
| "status_from": "steps.upstream.status_code", | ||
| }, nil) | ||
| if err != nil { | ||
| t.Fatalf("factory error: %v", err) | ||
| } | ||
|
|
||
| recorder := httptest.NewRecorder() | ||
| pc := NewPipelineContext(nil, map[string]any{ | ||
| "_http_response_writer": recorder, | ||
| }) | ||
| pc.MergeStepOutput("upstream", map[string]any{ | ||
| "status_code": float64(503), | ||
| }) | ||
|
|
||
| result, err := step.Execute(context.Background(), pc) | ||
| if err != nil { | ||
| t.Fatalf("execute error: %v", err) | ||
| } | ||
|
|
||
| resp := recorder.Result() | ||
| if resp.StatusCode != 503 { | ||
| t.Errorf("expected status 503 from float64 status_from, got %d", resp.StatusCode) | ||
| } | ||
| if result.Output["status"] != 503 { | ||
| t.Errorf("expected output status=503, got %v", result.Output["status"]) | ||
| } | ||
| } |
There was a problem hiding this comment.
Test coverage for status_from doesn’t currently cover invalid resolved values (e.g. a float64 with a fractional part, or an out-of-range status like 0/9999). Adding a couple of negative tests would help lock in the intended “valid integer only, otherwise fall back” behavior once validation is added in resolveStatus.
⏱ Benchmark Results✅ No significant performance regressions detected. benchstat comparison (baseline → PR)
|
|
@copilot apply changes based on the comments in this thread |
…al, update schemas and tests Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> Agent-Logs-Url: https://github.com/GoCodeAlone/workflow/sessions/d591ca56-9504-43b4-8afb-21808a4d9e47
Applied in commit feb1e97:
|
Implements the
status_fromfield onstep.json_response, enabling dynamic HTTP status codes resolved from the pipeline context at runtime.Changes Made
module/pipeline_step_json_response.go: AddedstatusFromfield toJSONResponseStep, parsed from config in the factory. NewresolveStatus(pc)method resolves a dotted path (e.g.steps.call_upstream.status_code) viaresolveBodyFrom, handlingint,float64, andint64values. Resolved values are validated to be whole numbers within the valid HTTP status code range (100–599); fractional floats and out-of-range values fall back to the staticstatusfield (default 200).Executenow callsresolveStatus(pc)instead of using the static status directly.schema/step_schema_builtins.go: Addedstatus_fromConfigFieldDefto thestep.json_responseschema. Madestatusoptional (removedRequired: true, addedDefaultValue: "200") so configs using onlystatus_fromare valid.schema/module_schema.go: Addedstatus_fromfield to thestep.json_responseModuleSchemaused by UI/editor tooling.module/pipeline_step_json_response_test.go: Added tests coveringstatus_fromwith integer value, float64 value, fallback on missing path, precedence over staticstatus, no-HTTP-writer scenario, fractional float fallback, out-of-range status codes (0, -1, 9999, 99, 600), and boundary-valid codes (100, 599).DOCUMENTATION.md: Updatedstep.json_responsetable entry to mentionstatus_from.Behavior
status_fromaccepts a dotted path reference (e.g.steps.call_upstream.status_code) resolved at runtime from the pipeline contextstatus_fromresolves to a valid whole-number integer within the HTTP range (100–599), it is used as the HTTP status code404.9) and out-of-range values are rejected and fall back tostatusstatusandstatus_fromare provided,status_fromtakes precedence when resolved to a valid codestatus_fromis absent or resolves to an invalid/missing value, falls back tostatus(or 200 default)statusis now optional in schema validation;status_fromalone is a valid configurationExample
Testing
status_frombehaviors including integer, float64, fallback, precedence, no-writer, fractional float rejection, out-of-range rejection, and boundary validationOriginal prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.