Handle errors in a NextPDF Connect workflow
At a glance
Section titled “At a glance”Build resilient Connect workflows. Validate every tool result, close a failed session, and retry from fresh state. A failed tool returns a structured error result. Treat that result as a normal response, not a transport failure. PHP Standards Recommendation (PSR)-18 makes the same distinction: a response is returned even when the status indicates an error (PSR-18 §3).
Install
Section titled “Install”composer require nextpdf/serverBind a transport. This recipe uses create_pdf, add_text, and output_pdf.
All three tools are Core.
Conceptual overview
Section titled “Conceptual overview”A failed tool call returns an error result. The result carries an error flag, a human-readable message, and a code where applicable. A successful result has no error flag and carries the tool’s normal output. In both cases, the transport sent the request and received the response (PSR-18 §p2).
Keep the defensive loop short. Send the call, then read the result. If the result is an error, log it, classify it, apply the recovery strategy, and stop using stale state. Otherwise, extract the fields you need and continue.
API surface
Section titled “API surface”| Tool | Role | Risk tier |
|---|---|---|
create_pdf | Open the session | Safe |
add_text | Write text | Caution |
output_pdf | Render and return the PDF | Approval Required / Review (base64) |
The tool catalog is the source of truth. The available tools depend on the installed tier.
Code sample — Quick start
Section titled “Code sample — Quick start”Run the happy path (create_pdf → add_text → output_pdf) and check each
result. Then intentionally reuse a destroyed document_id on add_text to
trigger a session error. Recover by creating a new session and replaying the
content.
Code sample — Production
Section titled “Code sample — Production”Classify errors by category, then respond accordingly:
- Input validation — deterministic. Fix the arguments, then retry the same call. Examples: empty text, invalid alignment, non-positive size, unknown page size, unknown font family.
- Session — the
document_idno longer exists. Create a new session, then replay all content. - System — a server resource constraint, such as the session limit. Back off, then retry.
- Approval —
output_pdfto a file may pause for human approval. This is a workflow pause, not a failure. Relay the challenge and wait, then re-call with the confirmation token.
Never assume success. Never reuse a document_id after a session error.
Never send output_pdf until every content step has succeeded.
Edge cases & gotchas
Section titled “Edge cases & gotchas”- Approval is not an error. The human-in-the-loop (HITL) challenge is a pause. Do not retry in a tight loop. Relay it to the human.
- Server restart. All in-memory sessions are cleared, and every prior
document_idbecomes invalid. - Partial workflow. If
add_textfails mid-document, the session may be inconsistent. The safe recovery is a fresh session, not a partial repair.
Performance
Section titled “Performance”Negligible. This recipe covers control flow, not rendering. The profile is
structural for any produced output.
Security notes
Section titled “Security notes”Error messages are for the calling agent and operator. Do not echo raw server error text verbatim to untrusted end users. Surface a classified, sanitized message instead.
Conformance
Section titled “Conformance”| Statement | Spec | Clause | reference_id |
|---|---|---|---|
| The transport returns a response regardless of result. | PSR-18 | §p2 | |
| A response is returned even on an error status. | PSR-18 | §3 |
Commercial context
Section titled “Commercial context”Not applicable — all tools are Core.
Transport availability
Section titled “Transport availability”| Transport | Available | Notes |
|---|---|---|
| MCP (stdio) | Yes | Errors arrive as a tool result with an error flag. |
| REST | Yes | A non-2xx status carries the same classified error body. |
| gRPC | Yes | A status code plus an error result message. |
In every transport, inspect a tool-level error as a normal response, not a dropped call (PSR-18 §3).
HITL risk tier
Section titled “HITL risk tier”create_pdf is Safe, add_text is Caution, and output_pdf is Approval
Required, downgraded to Review in base64 mode. A pending file write appears
as the approval challenge. The error loop must treat it as a pause, not a
failure (HITL risk tiers).
Confirmation gate JSON envelope
Section titled “Confirmation gate JSON envelope”A pending approval returns:
{ "allowed": false, "challenge": "<human-readable challenge text>", "token": "confirm_<single-use-hex>" }Re-call the same tool with _confirmation_token set to that token. It returns
{ "allowed": true }. For the full flow, see
output-approval.