How to handle errors and failed posts
Errors come in two places. A request can be rejected up front (HTTP 4xx), or it can be accepted and then fail on one platform later. The first shows up as an exception from the SDK. The second shows up in the post's per-channel result.error. Handle both.
The error envelope and every message are listed in the error reference.
What kinds of failure are there?
| Category | Examples | What to do |
|---|---|---|
| Your request | Bad slug, missing text, past scheduledAt | Fix the request. Do not retry. |
| Plan or guardrail | Upload limit, X allowance, daily key limit | Wait, raise the limit or upgrade. |
| Auth on a platform | reconnect_required | Refresh or reconnect, then retry. |
| Platform issue | Rate limit, 5xx | Retry later. |
| Network | Timeout, DNS | The TypeScript SDK retries safe GET requests for you. |
How do I catch typed errors in the TypeScript SDK?
import {
SocifyrError, AuthenticationError, PermissionError, ValidationError,
RateLimitError, UsageLimitError, NotFoundError,
} from '@socifyr/sdk'
try {
await socifyr.uploads.text({ connections: ['x-myhandle'], text: 'Hello' })
} catch (err) {
if (err instanceof ValidationError) {
console.error('Fix the request:', err.message, err.errors)
} else if (err instanceof RateLimitError) {
await new Promise((r) => setTimeout(r, err.retryAfter * 1000))
} else if (err instanceof UsageLimitError || err instanceof PermissionError) {
console.error('Plan, permission or guardrail block:', err.message)
} else if (err instanceof AuthenticationError) {
console.error('Check SOCIFYR_API_KEY')
} else if (err instanceof SocifyrError) {
console.error(err.status, err.code, err.message)
} else {
throw err
}
}Match on err.message when you need a specific case, because plan blocks and guardrail blocks both arrive as 403. See SDK errors and, for Python, Python SDK errors.
How do I handle a post that was accepted but failed?
const upload = await socifyr.uploads.text(params)
const result = await socifyr.uploads.waitForCompletion(upload.id!)
if (result.status === 'partial_failure' || result.status === 'failed') {
for (const ch of result.channels) {
if (ch.result?.status !== 'failed') continue
const error = ch.result.error ?? ''
if (error.startsWith('reconnect_required')) {
await socifyr.workspaces.refreshConnection(workspaceId, slugFor(ch))
}
}
await socifyr.uploads.retry(upload.id!)
}slugFor is your own lookup from ch.connectionId to a slug, using listConnections.
When should I retry?
| Error text contains | Retry? |
|---|---|
rate limit, 429, daily limit | Yes, after the window resets. |
timeout, network, temporarily, a 5xx code | Yes, after a few minutes. |
reconnect_required | Only after refresh or reconnect. |
permission, scope, 403 | No. Reconnect and grant permissions first. |
duplicate | No. Change the content. |
aspect ratio, duration, file size, caption too long | No. Fix the media or text. |
Connection "..." not found or not active | No. Fix the slug. |
How do I get notified instead of polling?
Subscribe a webhook to platform.failed and upload.partial_failure. See Webhooks. The payloads are in webhook payloads.
// inside your verified webhook handler
if (event.event === 'platform.failed') {
await queueRetry(event.payload.uploadId, { delayMinutes: 10 })
}What should I log?
Log the post ID and per-channel results. Never log the API key.
logger.info({
uploadId: upload.id,
status: result.status,
channels: result.channels.map((c) => ({
platform: c.platform,
status: c.result?.status,
error: c.result?.error,
})),
})FAQ
Does the SDK retry failed requests?
Only GET, HEAD and OPTIONS are retried automatically. Writes are not, so retry them yourself and use an idempotencyKey to avoid duplicates.
Where do I find the exact error messages?
In the error reference.