Обработка ошибок
Errors Exceptions
Обработка ошибок — это критически важная часть любого надежного программного обеспечения.
В программировании ошибки неизбежны. Они могут возникать по множеству причин: неправильный ввод пользователя, отсутствие файла, сетевые проблемы, ошибки в логике программы и т.д.
В Dart ошибки делятся на два основных типа:
- Errors (Ошибки): Представляют собой программные ошибки, которые указывают на проблемы в коде, которые разработчик должен исправить NullPointerException, OutOfMemoryError.
- Exceptions (Исключения): Представляют ситуации, которые могут возникнуть во время выполнения программы, но которые можно (и нужно) ожидать, "поймать" и обработать.
Основной механизм работы с исключениями
try, catch, finally
- try: Блок кода, "пытаемся" выполнить код и возможно поймать исключение
- catch: Блок кода, если внутри try было поймано исключение
- finally: Блок кода, который выполняется всегда
Например
Dart
void main() {
String text = 'Изучаем HTTP'; // Эта строка не может быть преобразована в число
try {
// Потенциально опасная операция
// "Пытаемся" её выполнить
int number = int.parse(text);
print('Число: $number');
} catch (e) { // e - это объект исключения
print('Произошла ошибка: $e');
print('Тип ошибки: ${e.runtimeType}'); // Показывает тип исключения
}
print('Программа продолжает выполнение.');
}
Вывод
Произошла ошибка: FormatException: Invalid radix-10 number (at character 1)
Изучаем HTTP
^
Тип ошибки: FormatException
Объяснение:
int.parse('Изучаем HTTP')выбрасываетFormatException, потому что 'Изучаем HTTP' не является целым числом.- Блок
catch (e)перехватывает это исключение. - Переменная
eсодержит информацию о произошедшей ошибке. - Программа не завершается аварийно, а продолжает выполнение после блока
try-catch.
Перехват определенных типов исключений
on ExceptionType перехватывает только исключения указанного типа
Можно иметь несколько блоков on
Они обрабатываются сверху вниз
Например
Dart
import 'dart:io';
void main() {
try {
// int.parse('Это обычная строка'); // Выбрасывает FormatException
File('Файла_которого_нет.txt').readAsStringSync(); // Выбрасывает FileSystemException
} on FormatException catch (e) {
print('Ошибка формата данных: $e');
} on FileSystemException catch (e) { // Этот блок не сработает, так как сработал FormatException
print('Ошибка файловой системы: ${e.message}');
} catch (e) { // Общий catch для любых других исключений
print('Произошла общая ошибка: $e');
} finally {
print('Завершение попытки.');
}
}
Вывод
Ошибка файловой системы: Cannot open file
Завершение попытки.
Выбрасывание своих исключений (throw)
Можно выбрасывать (throw) свои собственные исключения, когда в коде возникает ситуация, которую он не может обработать самостоятельно.
Например
Dart
// Создаём свой тип для исключения
class InvalidInputException implements Exception {
final String message;
InvalidInputException(this.message);
@override
String toString() => 'InvalidInputException: $message';
}
void processInput(String input) {
if (input.isEmpty) {
throw InvalidInputException('Пусто и грустно ...');
}
if (input.length < 5) {
throw ArgumentError('Входные данные слишком короткие');
}
print('Ок: $input');
}
void main() {
try {
processInput(''); // Выбросит InvalidInputException
// processInput('Ой'); // Выбросит ArgumentError
// processInput('Привет :)'); // Успешно
} on InvalidInputException catch (e) {
print('Ошибка: ${e.message}');
} on ArgumentError catch (e) {
print('Ошибка: ${e.message}');
} catch (e) {
print('Неизвестная ошибка: $e');
}
}
Вывод
Результат
Ошибка: Пусто и грустно ...
Обработка ошибок в асинхронном коде
try-catch блоки используются вокруг await выражений.
Dart
Future fetchData() async {
await Future.delayed(Duration(seconds: 3)); // Имитация задержки сети
// Имитация ошибки сети
throw Exception('Не удалось получить данные с сервера.');
// return 'Данные успешно получены!';
}
Future processData() async {
try {
String data = await fetchData(); // Ожидаем завершения Future
print('Данные: $data');
} catch (e) {
print('Ошибка при обработке данных: $e');
} finally {
print('Завершение асинхронной операции.');
}
}
void main() async {
print('Начало программы.');
await processData(); // Ожидаем завершения асинхронной функции
print('Программа завершена.');
}
Вывод
Результат
Начало программы.
Ошибка при обработке данных: Exception: Не удалось получить данные с сервера.
Завершение асинхронной операции.
Программа завершена.