Zum Hauptinhalt springen

Fehlerbehandlung

Diese Bibliothek bildet Mastodon-API-Fehler auf eine Sealed-Class-Hierarchie ab, deren Wurzel MastodonException ist.

Exception-Hierarchie​

MastodonException (sealed)
├── MastodonApiException // General HTTP response errors
│ ├── MastodonUnauthorizedException // 401 - Authentication error
│ ├── MastodonForbiddenException // 403 - Permission error
│ ├── MastodonNotFoundException // 404 - Resource not found
│ ├── MastodonRateLimitException // 429 - Rate limited
│ │ ├── retryAfter // Recommended wait duration
│ │ ├── limit // Request limit for the window
│ │ ├── remaining // Remaining requests
│ │ └── resetAt // Time when the window resets
│ ├── MastodonValidationException // 422 - Validation error
│ │ ├── serverMessage // Detailed server message
│ │ ├── details // Field errors by request field
│ │ └── MastodonAlreadyVotedException // Already voted
│ └── MastodonServerException // 5xx - Server error
├── MastodonNetworkException // Network connection error
└── MastodonAuthException (sealed) // OAuth authentication flow errors
├── MastodonAuthCancelledException // User cancelled
├── MastodonAuthStateMismatchException // CSRF detected
└── MastodonAuthTokenException // Token acquisition failed

Grundlegende Catch-Muster​

Alle Fehler abfangen​

try {
final status = await client.statuses.fetch(id);
} on MastodonException catch (e) {
print('Error: $e');
}

Nach HTTP-Status behandeln​

try {
final account = await client.accounts.fetchById(accountId);
} on MastodonNotFoundException {
print('Account not found');
} on MastodonUnauthorizedException {
print('Token is invalid. Please re-authenticate');
} on MastodonRateLimitException catch (e) {
print('Rate limited. Retry after ${e.retryAfter}');
} on MastodonApiException catch (e) {
print('API error (${e.statusCode}): ${e.message}');
} on MastodonNetworkException {
print('Check your network connection');
}

Details zu Validierungsfehlern abrufen​

try {
await client.accounts.create(request);
} on MastodonValidationException catch (e) {
print('Validation error: ${e.serverMessage}');
final details = e.details;
if (details != null) {
for (final entry in details.entries) {
for (final detail in entry.value) {
print('${entry.key}: ${detail.code} - ${detail.description ?? ''}');
}
}
}
}

details ist nach Request-Feldern gruppiert. Jeder MastodonValidationErrorDetail enthält den Fehlercode des Servers und eine optionale Beschreibung. Unbekannte Codes bleiben als Strings erhalten. Wenn ein Endpunkt nicht Mastodons erkanntes Format für Validierungsdetails liefert, ist details gleich null.

Besondere Exceptions​

MastodonAlreadyVotedException​

Wird ausgelöst, wenn versucht wird, in einer Umfrage abzustimmen, in der bereits abgestimmt wurde.

try {
await client.polls.vote(pollId, [0]);
} on MastodonAlreadyVotedException {
print('Already voted on this poll');
}

Rate-Limits behandeln​

MastodonRateLimitException stellt die X-RateLimit-*-Header von Mastodon bereit. Die empfohlene Wartezeit verwendet Retry-After, wenn der Server oder Proxy diesen Header liefert, andernfalls den Zeitstempel X-RateLimit-Reset.

Future<T> withRetry<T>(Future<T> Function() action) async {
try {
return await action();
} on MastodonRateLimitException catch (e) {
print('${e.remaining}/${e.limit} Anfragen verbleiben; Reset um ${e.resetAt}');
final wait = e.retryAfter ?? const Duration(seconds: 60);
await Future<void>.delayed(wait);
return action();
}
}

// Usage
final timeline = await withRetry(
() => client.timelines.fetchHome(limit: 20),
);