c# — Грамотное использование try-catch
Stack Overflow на русскомLoading…
- 0
- +0
- Тур Начните с этой страницы, чтобы быстро ознакомиться с сайтом
- Справка Подробные ответы на любые возможные вопросы
- Мета Обсудить принципы работы и политику сайта
- О нас Узнать больше о компании Stack Overflow
- Бизнес Узнать больше о поиске разработчиков или рекламе на сайте
- Войти Регистрация
-
текущее сообщество
- Stack Overflow на русском справка чат
Try/Catch/Finally / Habr
Когда вы используете Try/Catch/Finally, команда которая будет выполняться помещается в блок Try. Если произойдет ошибка в процессе выполнения команды, то она будет записана в переменную $Error, и выполнение скрипта перейдет к блоку Catch.Скрипт TestTryCatchFinally.ps1 использует команду Try в попытке создать объект. Объект создания находится в переменной $ob1. Командлет New-Object создает объект. После создания объекта и помещения его в переменную
Try
{
"Attempting to create new object $ob1"
$a = new-object $ob1
"Members of the $ob1"
"New object $ob1 created"
$a | Get-Member
}
Используйте блок Catch чтобы поймать ошибку, которая произошла в блоке Try. Вы можете указать тип ошибок для захвата, а также действие, которое бы происходило при возникновении ошибки. В скрипте TestTryCatchFinally.ps1 я слежу за ошибками типа System.Exception. Класс System.Exeption .Net Framework — это базовый класс, от которого зависят все другие исключения (exceptions). Это означает, что
Catch
{
[system.exception]
"caught a system exception"
}
Блок Finally последовательности Try/Catch/Finally всегда выполняется, независимо от того произошла ошибка или нет. Это означает что какие-то вещи для завершения, которые вы хотите сделать, например для явного освобождения COM объекта, следует помещать в блок Finally
Finally
{
"end of script"
}
Целиком скрипт TestTryCatchFinally.ps1:
TestTryCatchFinally.ps1
$ob1 = "kenobie"
"Begin test"
Try
{
"Attempting to create new object $ob1"
$a = new-object $ob1
"Members of the $ob1"
"New object $ob1 created"
$a | Get-Member
}
Catch [system.exception]
{
"caught a system exception"
}
Finally
{
"end of script"
}
Во время исполнения сценария TestTryCatchFinally.ps1 когда переменной $ob1 присваивается значение «kenobie» ошибка возникает потому что нет ни одного объекта с именем «kenobie», который можно было бы создать с помощью командлета
Как видно из предыдущей картинки, строка «Begin Test» выводится потому что находится за пределами цикла Try/Catch/Finally. Внутри блока Try строка “Attempting to create new object kenobie” выводится потому что, выполняется перед командой New-Object. Это демонстрирует то, что блок Try всегда пытается выполнить код внутри него. Члены объекта «kenobie» не выводятся, также как не выводится строка «new object kenobie created». Это указывает на то, что после возникновения ошибки сценарий переходит к следующему блоку. В блоке
Если в сценарии переменной $ob1 будет присвоено значение «system.object» (которое является корректным значением), блок Try успешно выполнится полностью. Это видно на следующем рисунке, члены объекты выведены, и строка указывающая чтоб объект успешно создан, также выводится. Блок Catch не срабатывает, а строка «end of script» из блока Finally выводится.
Вы можете использовать несколько блоков Catch в блоке Try/Catch/Finally. Нужно иметь в виду, что когда происходит исключение Windows Powershell покидает блок Try и ищет блок Catch. Будет использован первый блок Catch, который удовлетворит условиям исключения. Таким образом необходимо использовать наиболее конкретные исключения сначала, переходя к более общим.
Это видно в TestTryMultipleCatchFinally.ps1.
TestTryMultipleCatchFinally.ps1
$ob1 = "foo" "Begin test" $ErrorActionPreference = "stop" Try { Get-Content foo "Attempting to create new object $ob1" $a = new-object $ob1 "Members of the $ob1" "New object $ob1 created" $a | Get-Member } Catch [System.Management.Automation.PSArgumentException] { "invalid object" } Catch [system.exception] { "caught a system exception" } Finally { "end of script" }
Следующий рисунок показывает вывод сценария TestTryMultipleCatchFinally.ps1. Были сделаны два изменения: Закомментированы команды $ErrorActionPreference и Get-Content foo. Таким образом генерируемая ошибка будет возникать при попытке создать несуществующий объект. Чтобы найти конкретную ошибку, я исследовал переменную $error после запуска сценария TestTryMultipleCatchFinally.ps1. Ошибка указана в поле Exception.
PS C:\> $error | fl * -F PSMessageDetails : Exception : System.Management.Automation.PSArgumentException: Cannot find type [foo]: verify that the assembly containing this type is loaded. at System.Management.Automation.MshCommandRuntime.ThrowTerminat ingError(ErrorRecord errorRecord) TargetObject : CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand ErrorDetails : InvocationInfo : System.Management.Automation.InvocationInfo ScriptStackTrace : at <ScriptBlock>, C:\Users\dyak\SkyDrive\Scripts\habrahabr\TestTry MultipleCatchFinally.ps1: line 10 PipelineIterationInfo : {}
Если скрипт имеет несколько ошибок, а значение переменной $ErroActionPreference установлено в значение «stop», первая ошибка приведет к сбою сценария. Если убрать комментарии с команд $ErrorActionPreference и Get-Content, первая ошибка будет поймана блоком System.Exception Catch и поэтому будет пропущено исключение аргумента. Это видно на следующем рисунке:
В целом пытался перевести статью опубликованную в блоке Эда Уилсона. Надеюсь будет кому-то полезно.
habr.com
c# — Цикл внутри try…catch, как написать красивый код?
Stack Overflow на русскомLoading…
- 0
- +0
- Тур Начните с этой страницы, чтобы быстро ознакомиться с сайтом
- Справка Подробные ответы на любые возможные вопросы
- Мета Обсудить принципы работы и политику сайта
- О нас Узнать больше о компании Stack Overflow
- Бизнес Узнать больше о поиске разработчиков или рекламе на сайте
- Войти Регистрация
-
текущее сообщество
- Stack Overflow на русском справка чат
- Stack Overflow на русском Meta
ru.stackoverflow.com