← Назад к вопросам
Что выбрасывает программа когда происходит crash?
3.0 Senior🔥 81 комментариев
#Архитектура Flutter#Нативная интеграция#Тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Исключения при crash программы в Dart/Flutter
Когда происходит crash в программе на Dart, выбрасываются исключения (exceptions). Рассмотрим типы исключений и механизм их обработки.
Основные типы исключений
Exception — базовый класс
// Exception — все исключения наследуют от этого класса
class CustomException implements Exception {
final String message;
CustomException(this.message);
@override
String toString() => 'CustomException: $message';
}
Error — критические ошибки (редко ловят)
// Error — более серьезные ошибки (StackOverflowError, OutOfMemoryError)
// Обычно НЕ ловят, т.к. это признак серьезной проблемы
try {
// Код, который может выбросить ошибку
} on StackOverflowError catch (e) {
print('Stack overflow: $e');
}
Встроенные исключения Dart
ArgumentError — неправильный аргумент
void processAge(int age) {
if (age < 0) {
throw ArgumentError('Age must be positive');
}
}
// Использование
try {
processAge(-5);
} on ArgumentError catch (e) {
print('Argument error: ${e.message}');
}
FormatException — ошибка формата
void parseJson(String json) {
try {
final data = jsonDecode(json);
} on FormatException catch (e) {
print('Format error: ${e.message}');
}
}
// Пример
parseJson('{invalid json}'); // FormatException
UnsupportedError — неподдерживаемая операция
class ReadOnlyList<T> {
final List<T> _items;
ReadOnlyList(this._items);
void add(T item) {
throw UnsupportedError('Cannot add to read-only list');
}
}
RangeError — индекс вне диапазона
List<int> numbers = [1, 2, 3];
try {
print(numbers[10]); // RangeError
} on RangeError catch (e) {
print('Range error: $e');
}
NoSuchMethodError — метод не найден
Object obj = "hello";
try {
obj.nonExistentMethod(); // NoSuchMethodError
} on NoSuchMethodError catch (e) {
print('Method not found: $e');
}
NullPointerException (теоретически)
Благодаря null safety в Dart, NullPointerException не выбрасывается:
String? name = null;
// name.length; // Ошибка компиляции, не runtime!
// Вместо этого используем проверку:
if (name != null) {
print(name.length);
}
Иерархия исключений Dart
Object
├── Exception (обычные исключения)
│ ├── FormatException
│ ├── ArgumentError
│ ├── UnsupportedError
│ ├── RangeError
│ └── (custom exceptions)
└── Error (критические ошибки)
├── AssertionError
├── OutOfMemoryError
├── StackOverflowError
└── UnsupportedError
Обработка исключений
Try-catch
Future<void> fetchData() async {
try {
final response = await http.get(Uri.parse('api.example.com'));
if (response.statusCode != 200) {
throw Exception('Failed to load data');
}
} on SocketException {
print('Network error');
} on TimeoutException {
print('Request timeout');
} on FormatException {
print('Invalid response format');
} catch (e) {
print('Unknown error: $e');
}
}
Try-catch-finally
File file;
try {
file = File('data.txt');
final content = file.readAsStringSync();
print('Content: $content');
} on FileSystemException catch (e) {
print('File error: ${e.message}');
} finally {
// Выполнится в любом случае
print('Operation completed');
}
Кастомные исключения
// Базовое кастомное исключение
class AppException implements Exception {
final String message;
final String? code;
final dynamic originalException;
AppException({
required this.message,
this.code,
this.originalException,
});
@override
String toString() => 'AppException: $message (code: $code)';
}
// Специфичные исключения
class ApiException extends AppException {
final int? statusCode;
ApiException({
required String message,
this.statusCode,
String? code,
dynamic originalException,
}) : super(
message: message,
code: code,
originalException: originalException,
);
}
class AuthException extends AppException {
AuthException(String message)
: super(
message: message,
code: 'AUTH_ERROR',
);
}
class ValidationException extends AppException {
final Map<String, String> errors;
ValidationException({
required this.errors,
String message = 'Validation failed',
}) : super(message: message, code: 'VALIDATION_ERROR');
}
Практический пример обработки
Future<User> fetchUser(String userId) async {
try {
final response = await http.get(
Uri.parse('api.example.com/users/$userId'),
).timeout(Duration(seconds: 10));
if (response.statusCode == 401) {
throw AuthException('Unauthorized');
}
if (response.statusCode == 404) {
throw ApiException(
message: 'User not found',
statusCode: 404,
);
}
if (response.statusCode != 200) {
throw ApiException(
message: 'Failed to fetch user',
statusCode: response.statusCode,
);
}
return User.fromJson(jsonDecode(response.body));
} on TimeoutException {
throw ApiException(
message: 'Request timeout',
code: 'TIMEOUT',
);
} on SocketException {
throw ApiException(
message: 'Network error',
code: 'NETWORK_ERROR',
);
} catch (e) {
throw ApiException(
message: 'Unexpected error',
originalException: e,
);
}
}
Обработка в Flutter виджетах
class UserScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder<User>(
future: fetchUser('123'),
builder: (context, snapshot) {
if (snapshot.hasError) {
final error = snapshot.error;
if (error is AuthException) {
return Center(
child: Text('Please log in again'),
);
} else if (error is ApiException) {
return Center(
child: Text('API Error: ${error.message}'),
);
} else {
return Center(
child: Text('Unknown error: $error'),
);
}
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
final user = snapshot.data!;
return UserProfile(user: user);
},
);
}
}
Global Error Handling
void main() {
// Ловить необработанные исключения
FlutterError.onError = (FlutterErrorDetails details) {
print('Flutter Error: ${details.exceptionAsString()}');
// Логировать на сервер
logErrorToServer(details);
};
// Ловить ошибки вне Flutter фреймворка
PlatformDispatcher.instance.onError = (error, stack) {
print('Platform Error: $error');
// Логировать на сервер
logErrorToServer(error.toString(), stack);
return true;
};
runApp(MyApp());
}
Итого
Quando программа crashит, выбрасываются:
- Exception — обычные исключения (ArgumentError, FormatException, RangeError)
- Error — критические ошибки (StackOverflowError, OutOfMemoryError)
- Custom exceptions — кастомные исключения для бизнес-логики
Ключевые моменты:
- Всегда ловить и обрабатывать исключения
- Использовать специфичные типы исключений
- Создавать кастомные исключения для разных типов ошибок
- Не ловить Error (только в исключительных случаях)
- Логировать ошибки для отладки и мониторинга