Context (ctx)
Every hook except on_finished() receives a per-cycle context table as its second argument. It’s created fresh for each scrape cycle and discarded at the end.
Engine-Set Fields
Section titled “Engine-Set Fields”ctx.last_fetch
Section titled “ctx.last_fetch”FetchAttempt envelope representing the last network fetch.
| Field | Type | Description |
|---|---|---|
ok |
boolean | Whether the fetch succeeded |
request |
table | url, method, headers, timeout, proxy, max_body_size |
response |
table? | status, url, body, headers, time_ms, size, proxy (only on success) |
error |
table? | message, kind (only on failure) |
function after_extract(items, ctx) if ctx.last_fetch and ctx.last_fetch.ok then log("Fetch was successful: " .. ctx.last_fetch.response.status) end return itemsendctx.selector_matches
Section titled “ctx.selector_matches”Number of items found during extraction. Useful for detecting outdated selectors.
print("Found " .. #items .. " items (out of " .. ctx.selector_matches .. " selector hits)")ctx.telemetry
Section titled “ctx.telemetry”Performance telemetry for the current scraping cycle.
| Field | Type | Description |
|---|---|---|
job_name |
string | Name of the job |
start_time |
number | Epoch timestamp (seconds) when cycle started |
total_duration_ms |
number | Total duration of the cycle in milliseconds |
stages |
array | Sequence of stage records |
Stage record fields:
| Field | Type | Description |
|---|---|---|
name |
string | Stage name (e.g. before_fetch, fetch, override_extract) |
status |
string | success, error, or inactive |
type |
string | hook for Lua hooks, internal for engine-native stages |
duration_ms |
number | Stage execution time in milliseconds |
lua_mem_bytes |
number | Total Lua memory usage after the stage |
mem_delta_bytes |
number | Change in Lua memory during this stage |
browsers |
number | Number of active browser processes |
error |
string? | Error message if the stage failed |
function on_finally(ctx) if ctx.telemetry then log("Job completed in " .. ctx.telemetry.total_duration_ms .. "ms") for _, stage in ipairs(ctx.telemetry.stages) do log(" " .. stage.name .. ": " .. stage.duration_ms .. "ms (" .. stage.status .. ")") end endendctx.shared
Section titled “ctx.shared”A table for passing data between hooks within the same cycle.
function before_fetch(request, ctx) ctx.shared.start_time = os.clock() return requestend
function after_extract(items, ctx) local elapsed = os.clock() - ctx.shared.start_time log("Extraction took " .. elapsed .. " seconds") return itemsendctx.worker_id
Section titled “ctx.worker_id”1-based index for multi-worker jobs. Always 1 for single-worker jobs. Read-only.
function before_fetch(request, ctx) log("Worker " .. ctx.worker_id .. " processing") return requestendUser-Defined Fields
Section titled “User-Defined Fields”You can set any additional fields on ctx in any hook. They persist until the cycle ends.
function before_fetch(request, ctx) ctx.my_custom_flag = true return requestend