All errors thrown by the SDK are instances of MaildenoError. Use instanceof to distinguish them from unexpected runtime errors.
Basic pattern
import { MaildenoClient, MaildenoError } from "maildeno"
const client = new MaildenoClient({ apiKey: process.env.MAILDENO_API_KEY! })
try {
const html = await client.renderHtml("template-id")
} catch (err) {
if (err instanceof MaildenoError) {
console.error(`[${err.code}] ${err.message} (HTTP ${err.status})`)
} else {
throw err // re-throw unexpected errors
}
}
Error properties
| Property | Type | Description |
|---|---|---|
|
|
Machine-readable error code. See Error codes below. |
|
|
Human-readable description from the API. |
|
|
HTTP status code. |
|
|
Populated on |
Error codes
| Code | HTTP status | When it occurs |
|---|---|---|
|
|
Key is missing, malformed, revoked, or expired. |
|
|
Key does not have scope for the requested target. See API Key Scopes. |
|
|
The |
|
|
Template data is invalid or the render pipeline failed. |
|
|
|
|
|
Request exceeded the configured |
Switch-based handler
try {
const html = await client.renderHtml("template-id")
} catch (err) {
if (!(err instanceof MaildenoError)) throw err
switch (err.code) {
case "INVALID_API_KEY":
console.error("Check your API key in the dashboard")
break
case "FORBIDDEN":
console.error("Key scope:", err.message)
break
case "TEMPLATE_NOT_FOUND":
console.error("Template not found — check the template ID")
break
case "RENDER_ERROR":
console.error("Render failed:", err.message)
if (err.issues) {
err.issues.forEach(i => console.error(i.loc.join("."), i.msg))
}
break
case "NETWORK_ERROR":
console.error("Network error — retrying may help")
break
case "TIMEOUT":
console.error("Request timed out — consider increasing the timeout")
break
}
}
Validation errors (err.issues)
When the API rejects a request because the input is malformed — for example, a templateId that is not a valid UUID — the SDK populates err.issues with every pydantic validation issue:
try {
await client.renderHtml("not-a-uuid")
} catch (err) {
if (err instanceof MaildenoError && err.issues) {
for (const issue of err.issues) {
console.error(issue.loc.join("."), issue.msg)
// → body.template_id Input should be a valid UUID, ...
}
}
}
Express middleware example
import { MaildenoError } from "maildeno"
import type { ErrorRequestHandler } from "express"
export const maildenoErrorHandler: ErrorRequestHandler = (err, req, res, next) => {
if (err instanceof MaildenoError) {
return res.status(err.status || 500).json({
error: err.code,
message: err.message,
issues: err.issues ?? [],
})
}
next(err)
}