Error Handling
Properly handling errors is essential for building robust messaging applications with the MsGine SDK.
Error Types
The SDK throws different types of errors depending on the situation:
MsGineError
The base error class for all API errors:
typescript
import { MsGineError } from '@msgine/sdk'
try {
await client.sms.send({
to: '+256701521269',
message: 'Hello!'
})
} catch (error) {
if (error instanceof MsGineError) {
console.error('MsGine API Error:', error.message)
console.error('Status Code:', error.statusCode)
console.error('Error Code:', error.code)
}
}MsGineValidationError
Thrown when input fails validation before reaching the API:
typescript
import { MsGineValidationError } from '@msgine/sdk'
try {
await client.sms.send({
to: 'invalid-number',
message: 'Hello!'
})
} catch (error) {
if (error instanceof MsGineValidationError) {
console.error('Validation failed:', error.message)
if (error.field) {
console.error('Invalid field:', error.field)
}
}
}Error Properties
| Class | Property | Type | Description |
|---|---|---|---|
MsGineError | message | string | Human-readable error description |
MsGineError | statusCode | number | HTTP status code (e.g., 400, 401, 500) |
MsGineError | code | string | Machine-readable error code |
MsGineValidationError | message | string | Validation failure description |
MsGineValidationError | field | string? | The field that failed validation |
Common Error Codes
Authentication Errors
typescript
{
code: 'unauthorized',
statusCode: 401,
message: 'Invalid or missing API key'
}Solutions:
- Verify your API key is correct
- Check that the key hasn't been revoked
- Ensure the key is properly loaded from environment variables
Validation Errors
typescript
{
code: 'invalid_phone_number',
statusCode: 400,
message: 'The phone number must be in E.164 format',
details: {
field: 'to',
value: '0701234567'
}
}Solutions:
- Use E.164 format:
+[country code][number] - Example:
+256701521269(not0701521269)
Rate Limit Errors
typescript
{
code: 'rate_limit_exceeded',
statusCode: 429,
message: 'Too many requests. Please try again later.',
details: {
retryAfter: 60
}
}Solutions:
- Implement request queuing for high-volume applications
- Respect the
retryAftervalue before retrying
Insufficient Balance
typescript
{
code: 'insufficient_balance',
statusCode: 402,
message: 'Insufficient account balance'
}Solutions:
- Top up your account at msgine.net/billing
- Monitor your balance before large sends
Error Handling Best Practices
1. Always Use Try-Catch
typescript
async function sendMessage() {
try {
const result = await client.sms.send({
to: '+256701521269',
message: 'Hello!'
})
return result
} catch (error) {
if (error instanceof MsGineValidationError) {
// Handle input validation errors
console.error('Invalid input:', error.message, error.field)
} else if (error instanceof MsGineError) {
// Handle API errors
console.error('API Error:', error.code, error.message)
} else {
// Handle unexpected errors
console.error('Unexpected error:', error)
}
throw error
}
}2. Check Error Codes
typescript
try {
await client.sms.send({ to: phone, message: text })
} catch (error) {
if (error instanceof MsGineError) {
switch (error.code) {
case 'invalid_phone_number':
console.error('Invalid phone:', error.details)
break
case 'rate_limit_exceeded':
console.error('Rate limited, retry after:', error.details?.retryAfter)
break
case 'unauthorized':
console.error('Authentication failed — check your API key')
break
case 'insufficient_balance':
console.error('Low balance — top up at msgine.net/billing')
break
default:
console.error('API error:', error.message)
}
}
}3. Graceful Degradation
typescript
async function sendSmsWithFallback(to: string, message: string) {
try {
return await client.sms.send({ to, message })
} catch (error) {
if (error instanceof MsGineError) {
// Log to monitoring service
await logToMonitoring(error)
// Attempt fallback notification method
await sendEmailNotification(to, message)
return null
}
throw error
}
}4. Retry on Transient Errors
typescript
async function sendWithRetry(to: string, message: string, maxAttempts = 3) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await client.sms.send({ to, message })
} catch (error) {
if (
error instanceof MsGineError &&
(error.statusCode === 429 || error.statusCode >= 500) &&
attempt < maxAttempts
) {
const delay = Math.pow(2, attempt) * 1000
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms`)
await new Promise(resolve => setTimeout(resolve, delay))
} else {
throw error
}
}
}
}Validation Errors
The SDK validates inputs before making API requests. This catches obvious mistakes early:
typescript
try {
await client.sms.send({
to: 'not-a-phone-number', // Will throw MsGineValidationError
message: 'Hello!'
})
} catch (error) {
if (error instanceof MsGineValidationError) {
// Validation happened client-side — no API call was made
console.error('Validation error:', error.message)
if (error.field) {
console.error('Problem field:', error.field)
}
}
}Next Steps
- Configuration - Configure the client
- Best Practices - Production tips
- Troubleshooting - Common issues