Best Practices
4. Handle Errors Gracefully
Always handle validation and sending errors gracefully.
Complete Error Handling
Codeimport { validateTemplateData, renderTemplate, getTemplate } from '@relay-works/templates'; import { RelayAPI } from '@relay-works/sdk-js'; async function sendTemplate( templateId: string, data: any, recipient: string ): Promise<{ success: boolean; messageId?: string; errors?: any }> { try { const template = getTemplate(templateId); // 1. Validate data const validation = validateTemplateData(template, data); if (!validation.valid) { console.error('Validation failed:', validation.errors); return { success: false, errors: validation.errors }; } // 2. Render template const result = renderTemplate(template, data); // 3. Send via Relay const relay = new RelayAPI({ apiKey: process.env.RELAY_API_KEY! }); const message = await relay.messages.send({ to: recipient, message: result.text }); return { success: true, messageId: message.id }; } catch (error) { console.error('Send failed:', error); return { success: false, errors: error instanceof Error ? error.message : 'Unknown error' }; } }
Validation Error Handling
Codeconst validation = validateTemplateData(template, data); if (!validation.valid) { // Log all validation errors validation.errors.forEach(error => { console.error(`Field ${error.field}: ${error.message}`); console.log(`Suggestion: ${error.suggestion}`); }); // Return user-friendly error throw new Error( `Template validation failed: ${validation.errors.map(e => e.message).join(', ')}` ); }
API Error Handling
Codetry { const message = await relay.messages.send({ to: recipient, message: result.text }); } catch (error) { if (error.response?.status === 429) { // Rate limit exceeded console.error('Rate limit exceeded, retry later'); } else if (error.response?.status === 400) { // Invalid phone number or message console.error('Invalid request:', error.response.data); } else if (error.response?.status === 401) { // Authentication failed console.error('Invalid API key'); } else { // Other errors console.error('Send failed:', error.message); } throw error; }
Retry Logic
Codeasync function sendWithRetry( templateId: string, data: any, recipient: string, maxRetries = 3 ) { let lastError; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return await sendTemplate(templateId, data, recipient); } catch (error) { lastError = error; console.log(`Attempt ${attempt} failed, retrying...`); // Wait before retrying (exponential backoff) await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000) ); } } throw lastError; }
User-Friendly Error Messages
Codefunction getUserFriendlyError(error: any): string { if (error.errors) { // Validation errors return 'Please check your input and try again.'; } if (error.response?.status === 429) { return 'Too many requests. Please try again later.'; } if (error.response?.status === 400) { return 'Invalid phone number or message format.'; } return 'Failed to send message. Please try again.'; } // Usage in API route try { await sendTemplate(templateId, data, recipient); return { success: true }; } catch (error) { return { success: false, message: getUserFriendlyError(error) }; }
Logging Best Practices
Codeimport { logger } from './utils/logger'; async function sendTemplate(templateId: string, data: any, recipient: string) { logger.info('Sending templated message', { templateId, recipient: recipient.slice(-4), // Only log last 4 digits timestamp: new Date().toISOString() }); try { const result = await sendTemplateInternal(templateId, data, recipient); logger.info('Message sent successfully', { messageId: result.messageId, segments: result.segments }); return result; } catch (error) { logger.error('Failed to send message', { templateId, error: error.message, stack: error.stack }); throw error; } }
Next Steps:
Last modified on