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),
);