Skip to main content

serverless-pre-function

serverless-pre-function

Runs a list of inline Lua functions as a single graph node, threading the Context through each in order. Place it before the upstream node (its serverless-post-function twin goes after). Each function has full read/write access to the Context, exactly like the script node.

Configuration

KeyTypeDefaultDescription
functionsarray of strings— (required, ≥1)Each string is Lua source defining a global execute(ctx) function. Compiled at config load.
phasestringAccepted for config compatibility, but inert — phase is expressed by the node's placement in the graph.
timeout_msinteger5000Per-function execution timeout passed to the Lua runtime (stored, not yet enforced by the VM).
modules_pathstringDirectory the sandboxed require resolves modules from.
- id: pre
type: serverless-pre-function
config:
phase: access # accepted for compatibility; inert
timeout_ms: 2000
functions:
- |
function execute(ctx)
ctx.request.headers["x-serverless"] = {"pre"}
return ctx
end
- |
function execute(ctx)
ctx.message.checked = true
return ctx
end

Each function must define a global execute(ctx) and return the (possibly modified) Context table. See the Lua scripting guide for the Context table shape.

Behavior

Every function string is compiled and validated once at policy-compile time (in from_config): a syntax error, a top level that fails to load, a missing execute, an empty functions array, or a non-string entry all reject the policy immediately — never a live request.

At request time the functions run in declaration order in fresh Lua VMs, threading the Context: the table one function returns is the input to the next. On success the final Context flows through the success port. If any function raises an error, that failure (LUA_EXECUTION_ERROR, etc.) is propagated immediately, routing the Context through the error port; later functions do not run.

Behavior notes

  • Function contract. featherbit reuses the script plugin's Lua runtime: each function defines a global function execute(ctx) ... return ctx end and receives/returns the marshalled Context table — the same contract as the script node. There is no conf argument.
  • Phase by graph position. featherbit expresses phase through placement in the policy graph: a serverless-pre-function node sits before the upstream node, a serverless-post-function node after it. The phase key is accepted for config compatibility but inert.
  • timeout_ms is stored but not yet enforced by the VM (same caveat as the script node).

Errors

The functions run on the shared Lua runtime, so a failure in any of them propagates immediately — later functions do not run. The node returns the Context with the error, so the graph engine routes through the error port and appends the error to context.errors; it prepares no response of its own, so what the caller sees is decided by the policy's error wiring, an error-handler, or the gateway's default 500.

Returning a second value from execute other than "success" is an error (LUA_BAD_PORT): these nodes have no respond port; a script that must answer the request belongs in a script node.

Behavior change in 0.11.0

Before 0.11.0 a second return value from execute was silently ignored. A function that returned ctx, "respond" (or any other named port) ran to completion as if it had returned ctx alone. It now fails with LUA_BAD_PORT instead.

CodeStatusWhen
LUA_EXECUTION_ERRORA function raised a runtime error.
LUA_LOAD_ERRORA function failed to load into the VM.
LUA_MARSHAL_ERRORThe Context could not be converted to a Lua table.
LUA_MISSING_EXECUTEA function defined no global execute.
LUA_UNMARSHAL_ERRORA returned table did not fit the ctx shape; the message names the field.
LUA_BAD_PORTA function returned a second value (e.g. return ctx, "respond"); this node type has no such port.

Load, missing-execute and syntax failures are normally caught at policy-compile time — they reach a live request only if the source changed underneath a compiled policy. The ctx table shape is documented on script.