SMS delivery failures logged; fallback email triggered after retries exhausted
Why it matters
When all SMS retries are exhausted and nothing happens, the customer receives no notification about their booking. A console.log on failure is not a delivery log — it evaporates on process restart and cannot be queried for support investigations. CWE-391 (unhandled failure) and CWE-770 (uncontrolled resource consumption by uncapped retry state) both apply. The compound failure is silent: the booking system shows confirmed, the customer never hears anything, and there is no record to diagnose or alert on. ISO 25010 reliability.fault-tolerance requires that delivery failures be observable and that an alternative communication path exist.
Severity rationale
High because exhausted SMS retries with no fallback leave the customer entirely uninformed and leave operations with no structured record to investigate or alert on.
Remediation
In the SMS job worker at src/jobs/sms-worker.ts, write delivery failures to a persistent log table and queue a fallback email after the final retry. The failure log must include at minimum booking_id, phone, error, attempt, and timestamp:
smsQueue.process('send-confirmation-sms', async (job) => {
try {
await twilioClient.messages.create({ body: job.data.message, from: process.env.TWILIO_PHONE!, to: job.data.phoneNumber })
} catch (error) {
await db.smsDeliveryLog.create({
data: {
booking_id: job.data.bookingId,
phone: job.data.phoneNumber,
error: error instanceof Error ? error.message : String(error),
attempt: job.attemptsMade,
timestamp: new Date(),
},
})
if (job.attemptsMade >= job.opts.attempts) {
await emailQueue.add('send-confirmation', {
bookingId: job.data.bookingId,
customerEmail: job.data.fallbackEmail,
})
} else {
throw error
}
}
})
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Booking Notifications & Reminders Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-391 — Unchecked Error Condition — failures silently swallowed
- cwe · CWE-770 — Allocation of Resources Without Limits or Throttling (unbound retry storms without rate limiting)
- iso-25010:2011 · reliability.fault-tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from booking-notifications-reminders·automated