or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdcore-messaging.mderror-handling.mdindex.md

error-handling.mddocs/

0

# Error Handling

1

2

PyFCM provides comprehensive exception handling for various Firebase Cloud Messaging error conditions. The error system helps developers identify and respond appropriately to different failure scenarios including authentication issues, server problems, and data validation errors.

3

4

## Capabilities

5

6

### Base Exception Class

7

8

Root exception class for all PyFCM-specific errors, providing a common base for exception handling.

9

10

```python { .api }

11

class FCMError(Exception):

12

"""

13

Base exception class for all PyFCM errors.

14

15

All PyFCM-specific exceptions inherit from this class,

16

enabling broad exception handling with `except FCMError`.

17

"""

18

```

19

20

### Authentication Errors

21

22

Errors related to API authentication, credentials, and authorization issues.

23

24

```python { .api }

25

class AuthenticationError(FCMError):

26

"""

27

Raised when API key not found or authentication fails.

28

29

Common causes:

30

- Invalid or missing service account file

31

- Incorrect project ID

32

- Expired or invalid OAuth2 credentials

33

- Missing required authentication parameters

34

35

Resolution:

36

- Verify service account file path and contents

37

- Ensure project ID matches the service account

38

- Check credential scopes and permissions

39

"""

40

```

41

42

### Registration Token Errors

43

44

Errors related to invalid, expired, or unregistered device tokens.

45

46

```python { .api }

47

class FCMNotRegisteredError(FCMError):

48

"""

49

Raised when device token is invalid, missing, or unregistered.

50

51

Common causes:

52

- App uninstalled from device

53

- App data cleared

54

- Token expired or rotated

55

- Invalid token format

56

57

Resolution:

58

- Remove token from database

59

- Request new token from client app

60

- Implement token refresh logic

61

"""

62

```

63

64

### Sender Authorization Errors

65

66

Errors when the authenticated sender doesn't match the token's registered sender.

67

68

```python { .api }

69

class FCMSenderIdMismatchError(FCMError):

70

"""

71

Raised when authenticated sender differs from token's registered sender.

72

73

Common causes:

74

- Using wrong service account for token

75

- Token registered with different Firebase project

76

- Cross-project token usage

77

78

Resolution:

79

- Verify service account matches token's project

80

- Use correct credentials for target project

81

- Re-register token with current project

82

"""

83

```

84

85

### Server Errors

86

87

Errors indicating Firebase Cloud Messaging service issues or connectivity problems.

88

89

```python { .api }

90

class FCMServerError(FCMError):

91

"""

92

Raised for internal server errors or service timeouts.

93

94

Common causes:

95

- FCM service temporarily unavailable

96

- Network connectivity issues

97

- Server overload or maintenance

98

- Request timeout

99

100

Resolution:

101

- Implement retry logic with exponential backoff

102

- Check FCM service status

103

- Verify network connectivity

104

- Increase timeout values if needed

105

"""

106

```

107

108

### Data Validation Errors

109

110

Errors related to incorrect data format, structure, or validation failures.

111

112

```python { .api }

113

class InvalidDataError(FCMError):

114

"""

115

Raised when input data is incorrectly formatted or structured.

116

117

Common causes:

118

- Invalid JSON in configuration objects

119

- Wrong data types for parameters

120

- Missing required fields

121

- Data exceeding size limits (4KB payload limit)

122

123

Resolution:

124

- Validate input data structure

125

- Check parameter types and formats

126

- Ensure data payload within size limits

127

- Review FCM API documentation for requirements

128

"""

129

```

130

131

### Internal Package Errors

132

133

Errors indicating internal PyFCM processing issues.

134

135

```python { .api }

136

class InternalPackageError(FCMError):

137

"""

138

Raised for JSON parsing errors or internal package issues.

139

140

This error indicates a problem within PyFCM itself,

141

typically related to response parsing or internal state.

142

143

Resolution:

144

- Report issue to PyFCM maintainers

145

- Include error details and reproduction steps

146

- Check for known issues in project repository

147

"""

148

```

149

150

### Retry Control Exceptions

151

152

Exceptions for handling FCM retry-after responses and flow control.

153

154

```python { .api }

155

class RetryAfterException(Exception):

156

"""

157

Raised when FCM returns Retry-After header requiring delay.

158

159

Attributes:

160

- delay (int): Seconds to wait before retrying

161

162

Note: This exception must be handled by external logic

163

as it requires application-specific retry strategies.

164

"""

165

166

def __init__(self, delay):

167

"""

168

Initialize with retry delay.

169

170

Parameters:

171

- delay (int): Seconds to wait before retry

172

"""

173

self.delay = delay

174

```

175

176

## Usage Examples

177

178

### Basic Error Handling

179

180

```python

181

from pyfcm import FCMNotification

182

from pyfcm.errors import (

183

AuthenticationError,

184

FCMNotRegisteredError,

185

FCMServerError,

186

InvalidDataError

187

)

188

189

fcm = FCMNotification(

190

service_account_file="service-account.json",

191

project_id="your-project-id"

192

)

193

194

try:

195

result = fcm.notify(

196

fcm_token="device_token",

197

notification_title="Test Message",

198

notification_body="Testing error handling"

199

)

200

print(f"Message sent successfully: {result['name']}")

201

202

except AuthenticationError as e:

203

print(f"Authentication failed: {e}")

204

# Handle credential issues

205

206

except FCMNotRegisteredError as e:

207

print(f"Invalid token: {e}")

208

# Remove token from database

209

210

except FCMServerError as e:

211

print(f"FCM service error: {e}")

212

# Implement retry logic

213

214

except InvalidDataError as e:

215

print(f"Data validation error: {e}")

216

# Fix data format issues

217

```

218

219

### Comprehensive Error Handling

220

221

```python

222

from pyfcm.errors import FCMError

223

import time

224

import logging

225

226

def send_with_retry(fcm, **kwargs):

227

"""Send notification with retry logic and comprehensive error handling"""

228

max_attempts = 3

229

base_delay = 1

230

231

for attempt in range(max_attempts):

232

try:

233

return fcm.notify(**kwargs)

234

235

except AuthenticationError as e:

236

logging.error(f"Authentication error (not retryable): {e}")

237

raise # Don't retry authentication errors

238

239

except FCMNotRegisteredError as e:

240

logging.warning(f"Token unregistered: {e}")

241

# Remove token from database

242

return None

243

244

except FCMServerError as e:

245

if attempt < max_attempts - 1:

246

delay = base_delay * (2 ** attempt)

247

logging.warning(f"Server error, retrying in {delay}s: {e}")

248

time.sleep(delay)

249

continue

250

else:

251

logging.error(f"Server error after {max_attempts} attempts: {e}")

252

raise

253

254

except InvalidDataError as e:

255

logging.error(f"Data validation error (not retryable): {e}")

256

raise # Don't retry data errors

257

258

except FCMError as e:

259

logging.error(f"Unknown FCM error: {e}")

260

raise

261

```

262

263

### Batch Operation Error Handling

264

265

```python

266

def handle_batch_responses(responses, tokens):

267

"""Process batch operation responses and handle errors"""

268

successful = []

269

failed_tokens = []

270

271

for i, (response, token) in enumerate(zip(responses, tokens)):

272

try:

273

if 'error' in response:

274

error_code = response['error'].get('status', 'UNKNOWN')

275

276

if error_code == 'NOT_FOUND':

277

# Token no longer valid

278

failed_tokens.append(token)

279

logging.warning(f"Token {i} invalid, removing: {token}")

280

281

elif error_code == 'INVALID_ARGUMENT':

282

logging.error(f"Token {i} data error: {response['error']}")

283

284

else:

285

logging.error(f"Token {i} unknown error: {response['error']}")

286

else:

287

successful.append(response['name'])

288

289

except KeyError as e:

290

logging.error(f"Unexpected response format for token {i}: {e}")

291

292

return successful, failed_tokens

293

```

294

295

### Token Management with Error Handling

296

297

```python

298

class TokenManager:

299

"""Manage FCM tokens with automatic error handling and cleanup"""

300

301

def __init__(self, fcm_client):

302

self.fcm = fcm_client

303

self.invalid_tokens = set()

304

305

def send_to_token(self, token, **kwargs):

306

"""Send message with automatic token validation"""

307

if token in self.invalid_tokens:

308

return None

309

310

try:

311

return self.fcm.notify(fcm_token=token, **kwargs)

312

313

except FCMNotRegisteredError:

314

# Mark token as invalid and remove from storage

315

self.invalid_tokens.add(token)

316

self.remove_token_from_database(token)

317

return None

318

319

except FCMSenderIdMismatchError:

320

# Token belongs to different project

321

self.invalid_tokens.add(token)

322

return None

323

324

def remove_token_from_database(self, token):

325

"""Remove invalid token from persistent storage"""

326

# Implementation depends on storage system

327

pass

328

```

329

330

## Error Response Codes

331

332

PyFCM maps HTTP status codes to appropriate exceptions:

333

334

- **200**: Success

335

- **400**: InvalidDataError - Malformed request

336

- **401**: AuthenticationError - Invalid credentials

337

- **403**: FCMSenderIdMismatchError - Sender not authorized for token

338

- **404**: FCMNotRegisteredError - Token not found/registered

339

- **500+**: FCMServerError - Server errors and timeouts

340

341

## Best Practices

342

343

### Retry Strategies

344

345

- **Don't retry**: AuthenticationError, InvalidDataError, FCMSenderIdMismatchError

346

- **Retry with backoff**: FCMServerError

347

- **Remove and don't retry**: FCMNotRegisteredError

348

349

### Logging and Monitoring

350

351

```python

352

import logging

353

354

# Configure logging for error tracking

355

logging.basicConfig(

356

level=logging.INFO,

357

format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'

358

)

359

360

# Log all FCM operations for monitoring

361

logger = logging.getLogger('pyfcm_operations')

362

```

363

364

### Token Lifecycle Management

365

366

1. **Registration**: Store tokens securely with metadata

367

2. **Validation**: Handle registration errors during messaging

368

3. **Refresh**: Implement client-side token refresh logic

369

4. **Cleanup**: Remove invalid tokens promptly