Обработка исключений

Блок try..catch

Последнее обновление: 09.04.2023

В процессе работы прогаммы могут возникать различные ошибки, которые нарушают привычный ход программы и даже заставляют ее прервать выполнение. Такие ошибки называются исключениями. Язык Dart, как и многие языки программирования, поддерживает обработку исключений, что позволяет нам избежать аварийного прерывания работы программы.

Рассмотим простейшую ситуацию:

void main (){
     
	 int x = 9;
	 int y = 0;
	 int z = x ~/ y;
	 
	 print(z);
}

В данном случае происходит целочисленное деление (операция ~/) на 0. В итоге на программа сгенерирует исключение и завершит свое выполнение. Ситуация может показаться искуственной, так как здесь мы очевидно видим, что одна из переменных равна 0, и естественно программа завершится с ошибкой.

c:\dart>dart main.dart
Unhandled exception:
IntegerDivisionByZeroException
#0      int.~/ (dart:core-patch/integers.dart:30:7)
#1      main (file:///c:/dart/main.dart:5:16)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)

c:\dart>

Однако в реальности мы можем получать данные из внешнего источника и точно не знать, какое там значение 0 или не 0. Кроме того, делением на ноль исключения в Dart не ограничиваются, есть много ситуаций, где возможна подобная аварийная остановка работа программы.

Что нам предлагает Dart для обработки подобных ситуаций? Прежде всего это конструкция try...on...catch...finally:

try{
    // Код, который может привести к генерации исключения  
}
on Тип_Исключения{
     // Обработка возникшего исключения
}
catch (e){
     // Обработка возникшего исключения
}
finally{
     // 
}

При использовании блока try..on..catch..finally вначале выполняются все инструкции в блоке try. Если в этом блоке не возникло исключений, то после его выполнения начинает выполняться блок finally. И затем конструкция try..on..catch..finally завершает свою работу.

Если же в блоке try вдруг возникает исключение, то обычный порядок выполнения останавливается, то выполнение программы переходит к блоку on или catch, который может обработать возникшее исключение. Если нужный блок on или блок catch найден, то он выполняется, и после его завершения выполняется блок finally.

Разница между операторами on и catch состоит в том, что on обрабатывает исключение определенного типа (подробнее оператор on рассматривается в следующей теме). А catch обрабатывает все исключения.

Если нужный блок on или блок catch не найден, то при возникновении исключения опять же выполняется блок finally, а затем программа аварийно завершает свое выполнение.

Применим конструкцию try..on..catch..finally для обработки деления на 0:

void main (){
     
	 try{
		int x = 9;
		int y = 0;
		int z = x ~/ y;
	 
		print(z);
	}
	catch(e){
		 print("Возникло исключение $e");
	}
	print("Завершение программы");
}

Здесь код, который может сгенерировать исключение, помещен в блок try. Блок catch в скобках содержит список параметров, которые передаются при генерации исключении. В данном случае это один параметр - (e), который представляет информацию об исключении.

И при выполнении данной программы мы получим следующий консольный вывод:

Возникло исключение IntegerDivisionByZeroException
Завершение программы

Здесь мы видим, что несмотря на генерацию исключение, программа не завершилась аварийно, а после выполнения блока catch продолжила свою работу.

При определении конструкции мы можем опускать ряд блоков, если они не нужны. Только блок try является обязательным. Однако вместе с ним должен также использоваться, как минимум, либо блок on и(или) catch, либо блок finally. Так, в примере выше использовались только блоки try и catch. Добавим блок finally:

void main (){
     
	 try{
		int x = 9;
		int y = 0;
		int z = x ~/ y;
	 
		print(z);
	}
	catch(e){
		 print("Возникло исключение $e");
	}
	finally{
		 print("Выполнение блока finally");
	}
	print("Завершение программы");
}

Консольный вывод:

Возникло исключение IntegerDivisionByZeroException
Выполнение блока finally
Завершение программы

В данном случае мы можем опустить блок catch:

void main (){
     
	 try{
		int x = 9;
		int y = 0;
		int z = x ~/ y;
	 
		print(z);
	}
	finally{
		 print("Выполнение блока finally");
	}
	print("Завершение программы"); 	// эта строка не выполняется
}

После генерации исключения в блоке try выполняется блок finally, после чего программа аварийно останавливает свою работу. Консольный вывод:

Выполнение блока finally
Unhandled exception:
IntegerDivisionByZeroException
#0      int.~/ (dart:core-patch/integers.dart:30:7)
#1      main (file:///c:/dart/main.dart:6:13)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)

Параметры блока catch

В блок catch передается ряд параметров, которые несут информацию об исключении и мы можем при необходимости получить и использовать эту информацию:

void main (){
     
	try{
        int x = 9;
        int y = 0;
        int z = x ~/ y;
        
        print(z);
    }
    catch(e, s){
        print("Обработка исключения $e");
        print("Стек $s");
    }
	print("Завершение программы"); 
}

Первый параметр блока catch - e представляет объект исключения, а второй - s - стек исключений, который позволяет понять, где произошло исключение. Консольный вывод в данном случае:

Обработка исключения IntegerDivisionByZeroException
Стек #0      int.~/ (dart:core-patch/integers.dart:30:7)
#1      main (file:///c:/dart/main.dart:6:12)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)

Завершение программы

Так, по консольному выводу можно увидеть, что проблема в 6 строке файла c:/dart/main.dart, где сообственно и возикло исключение.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850