Skip to content

Intelligent error recovery: conditional retry + Handlebars context escaping #53

@ameet

Description

@ameet

Two related improvements to error handling and data safety

1. Conditional retry based on error type (extends #48)

Problem: The current retry mechanism treats all failures identically. There's no way to distinguish transient errors (429 rate limit, 502 gateway timeout, network flake) from permanent errors (401 auth failure, 403 forbidden, 404 not found). Every flow uses the same retries: 2, retryDelayMs: 1000 because there's no conditional logic.

This causes two problems:

  • Wasting time retrying permanent failures (e.g., retrying a 401 won't fix auth)
  • Not retrying enough for transient failures (e.g., a 429 needs backoff, not fixed 1s delay)

The Perplexity proxy bypass (#23) exists partly because the retry strategy can't detect 502s and back off.

Proposed solution:

{
  "onError": {
    "strategy": "retry",
    "retries": 3,
    "backoff": {
      "type": "exponential",
      "initialDelayMs": 1000,
      "multiplier": 2,
      "maxDelayMs": 30000
    },
    "retryOn": [429, 502, 503, "ETIMEDOUT", "ECONNRESET"],
    "failFastOn": [401, 403, 404]
  }
}

When a step fails:

  • If the error matches failFastOn → immediately fail (no retry)
  • If the error matches retryOn → retry with backoff
  • If neither matches → fall back to current behavior

Impact: 75 flows have error handling. Conditional retry would eliminate direct-curl bypasses for long-running APIs and reduce wasted time on permanent failures.

2. Handlebars context-aware escaping (extends #41)

Problem: Handlebars has one escaping mode, but interpolated values land in 4 different contexts: shell commands, JSON payloads, URLs, and markdown/HTML. A company name like O'Brien & Co. will:

  • Break shell commands (unescaped quote)
  • Break JSON (unescaped quote)
  • Break URLs (unescaped ampersand)
  • Break HTML (unescaped ampersand)

We run a multi-layer content sanitization step as a post-hoc defense, but prevention would be cheaper.

Proposed solution — pipe-based escaping in Handlebars:

{{ companyName | json }}     → JSON.stringify escaping
{{ companyName | shell }}    → shell-safe escaping (quotes, special chars)
{{ companyName | url }}      → encodeURIComponent
{{ companyName | md }}       → markdown-safe (escape brackets, pipes)
{{ companyName | html }}     → HTML entity escaping

Impact: Reduces reliance on defensive post-processing. Prevents a class of injection bugs at the template level. Affects 60+ flows that interpolate user-provided data.

Relationship to existing issues

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions