Skip to content

Publishing to social platforms is inherently unreliable — tokens expire, platforms rate-limit, network blips happen. The trick is to fail loudly when it's your bug, and recover quietly when it's not.

Categories of failure

CategoryExamplesWhat to do
Your buginvalid slug, missing field, wrong formatFix the request; don't retry
Auth issueexpired token, revoked OAuthNotify the user to reconnect
Platform issuerate limit, transient 5xxRetry with backoff
Network issueDNS, timeoutSDK retries automatically

Detecting categories

typescript
import { SocifyrError } from '@socifyr/sdk'

try {
  await socifyr.uploads.text(params)
} catch (err) {
  if (!(err instanceof SocifyrError)) throw err

  // Auth issue — surface to user
  if (err.message.includes('Token has expired') || err.message.includes('revoked')) {
    notifyUser('Please reconnect this platform')
    return
  }

  // Validation / your bug
  if (err.status === 400) {
    logError(err)
    throw err
  }

  // Rate limit
  if (err.status === 429) {
    await sleep(60_000)
    return retry()
  }

  // Everything else — log + rethrow
  logError(err)
  throw err
}

Partial failures

When a post fans out to N platforms, some can succeed and others fail:

typescript
const upload = await socifyr.uploads.text(params)
const result = await socifyr.uploads.waitForCompletion(upload.id)

if (result.status === 'partial_failure') {
  const failed = result.channels.filter(c => c.result?.status === 'failed')

  for (const ch of failed) {
    console.warn(`${ch.platform}: ${ch.result?.error}`)
  }

  // Retry just the failed ones (idempotent — succeeded channels are skipped)
  await socifyr.uploads.retry(upload.id)
}

When to retry

Error message containsRetry?
rate limitYes, after a delay
timeoutYes (SDK already retries; consider re-retry from your code if persistent)
Token has expiredNo — user must reconnect
Token is invalidNo — user must reconnect
connections should not be emptyNo — fix your request
caption too longNo — fix your content
Platform "...is temporarily unavailable"Yes, after several minutes

Webhook-driven retries

In production, prefer webhooks over polling. Subscribe to channel.failed and upload.failed to drive retries:

typescript
app.post('/webhooks/socifyr', async (req, res) => {
  if (!verifyWebhook(req)) return res.status(401).end()

  const { event, data } = req.body

  if (event === 'channel.failed' && isRetryableError(data.error)) {
    await scheduleRetry(data.uploadId, { delayMinutes: 10 })
  }

  res.json({ ok: true })
})

Logging

Log enough context to debug, never log the API key. The fields you want:

typescript
{
  uploadId: upload.id,
  connections: params.connections,
  status: result.status,
  channels: result.channels.map(c => ({
    platform: c.platform,
    status: c.result?.status,
    error: c.result?.error,
  })),
}