Skip to content

Handle errors in a NextPDF Connect workflow

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).

Terminal window
composer require nextpdf/server

Bind a transport. This recipe uses create_pdf, add_text, and output_pdf. All three tools are Core.

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.

ToolRoleRisk tier
create_pdfOpen the sessionSafe
add_textWrite textCaution
output_pdfRender and return the PDFApproval Required / Review (base64)

The tool catalog is the source of truth. The available tools depend on the installed tier.

Run the happy path (create_pdfadd_textoutput_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.

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_id no longer exists. Create a new session, then replay all content.
  • System — a server resource constraint, such as the session limit. Back off, then retry.
  • Approvaloutput_pdf to 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.

  • 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_id becomes invalid.
  • Partial workflow. If add_text fails mid-document, the session may be inconsistent. The safe recovery is a fresh session, not a partial repair.

Negligible. This recipe covers control flow, not rendering. The profile is structural for any produced output.

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.

StatementSpecClausereference_id
The transport returns a response regardless of result.PSR-18§p2
A response is returned even on an error status.PSR-18§3

Not applicable — all tools are Core.

TransportAvailableNotes
MCP (stdio)YesErrors arrive as a tool result with an error flag.
RESTYesA non-2xx status carries the same classified error body.
gRPCYesA 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).

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).

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.