Ответ
При необработанном исключении в Dart выбрасывается объект, унаследованный от класса Error или Exception, и выполнение потока прерывается.
Основные типы ошибок, которые я чаще всего вижу в логах:
RangeError(подклассError): Выход за границы коллекции.var list = [1, 2]; print(list[5]); // RangeError (index): Invalid value: Not in range 0..1, inclusiveNoSuchMethodError(подклассError): Вызов метода или геттера уnullили несуществующего члена.String? nullableString; print(nullableString.length); // NoSuchMethodError: The getter 'length' was called on null.StateError: Нарушение инварианта объекта (например, вызовaddна закрытомEventSink).
Обработка: Для глобального перехвата таких ошибок в Flutter-приложении я настраиваю:
void main() {
FlutterError.onError = (details) {
// Отправляем в Crashlytics/Sentry
myCrashReportingTool.recordError(details.exception, details.stack);
};
PlatformDispatcher.instance.onError = (error, stack) {
// Перехват ошибок вне контекста Flutter
myCrashReportingTool.recordError(error, stack);
return true; // Предотвращаем завершение изолятора
};
runApp(const MyApp());
}
Это позволяет логировать краши и, по возможности, gracefully завершать работу приложения.
Ответ 18+ 🔞
А, ну это же классика, ёпта! Смотри, когда в Dart'е какая-то хрень случается — вылетает необработанное исключение, — то летит объект, который наследуется либо от Error, либо от Exception. И всё, поток выполнения накрывается медным тазом, привет.
Вот какие косяки я чаще всего в логах наблюдаю, ядрёна вошь:
-
RangeError(это подклассError): Это когда кто-то полез куда не надо, за границы коллекции. Типичный распиздяй.var list = [1, 2]; print(list[5]); // RangeError (index): Invalid value: Not in range 0..1, inclusiveНу и что он хотел-то, с пятого элемента? Его же нихуя нет!
-
NoSuchMethodError(тоже подклассError): Это святое. Вызов метода или геттера уnull. Любимая ошибка всех, кто про?забывает.String? nullableString; print(nullableString.length); // NoSuchMethodError: The getter 'length' was called on null.Ну да, конечно, у
nullесть свойствоlength, ага, щас. Доверия ебать ноль к такому коду. -
StateError: Это когда объект в таком состоянии, что с ним уже нельзя вот эту конкретную операцию делать. Например, пытаться что-то добавить в уже закрытыйEventSink. Сам от себя охуеешь, когда такое в продакшене увидишь.
Обработка: Чтобы эти все летящие во все дыры ошибки не добили приложение окончательно, в Flutter'е я обычно настраиваю глобальные перехватчики. Э сабака сука, без них никуда.
void main() {
FlutterError.onError = (details) {
// Отправляем в Crashlytics/Sentry
myCrashReportingTool.recordError(details.exception, details.stack);
};
PlatformDispatcher.instance.onError = (error, stack) {
// Перехват ошибок вне контекста Flutter
myCrashReportingTool.recordError(error, stack);
return true; // Предотвращаем завершение изолятора
};
runApp(const MyApp());
}
Так хоть какая-то польза: краши логируются, и можно попытаться приложение не аварийно закрыть, а как-то по-человечески. А то волнение ебать каждый раз, когда юзер пишет «ваше приложение закрылось».