2015-10-10 2 views
1

Это my last question и просто запрос для уточнения.Правильно ли это иметь дело с ошибками/исключениями в конвейерах?

Потому что ThrowTerminatingError() прекратит выполнение командлета и прекратит обработку элементов в конвейере. Каков правильный способ решения проблемных объектов в конвейере, но вы все еще хотите продолжить обработку оставшихся элементов?

Я буду использовать очень тривиальный пример здесь, рассмотрим эту функцию:

Function Do-Something 
{ 

    [CmdletBinding()] 
    Param(
     [Parameter(Mandatory=$True, 
     ValueFromPipeline=$True)] 
     [int]$value 
    ) 

    process 
    { 
     if($value -eq 3) 
     { 
      // Terminate if $value is 3. 
     } 
     Write-Output($value) 
    } 
} 

Теперь предположим эта функция вызывается время как так ...

1..10 | Do-Something 

Использование throw:

if($value -eq 3) 
{ 
    throw '$value was 3' 
} 

Это выход:

1 
2 
$value was 3 
At C:\Users\Me\Desktop\Untitled1.ps1:51 char:12 
+   throw '$value was 3' 
+   ~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : OperationStopped: ($value was 3:String) [], RuntimeException 
    + FullyQualifiedErrorId : $value was 3 

Использование ThrowTerminatingError():

if($value -eq 3) 
{ 
    $PSCmdlet.ThrowTerminatingError((New-Object System.Management.Automation.ErrorRecord -ArgumentList (new-object System.Exception -ArgumentList ('$value was 3')), 'ValueWas3', 'NotSpecified', $value))  
} 

Формирует аналогичный вывод:

1 
2 
Do-Something : $value was 3 
At C:\Users\Me\Desktop\Untitled1.ps1:57 char:9 
+ 1..10 | Do-Something 
+   ~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (3:Int32) [Do-Something], Exception 
    + FullyQualifiedErrorId : ValueWas3,Do-Something 

Однако, если я использую Write-Error и оператор возврата:

if($value -eq 3) 
{ 
    Write-Error((New-Object System.Management.Automation.ErrorRecord -ArgumentList (new-object System.Exception -ArgumentList ('$value was 3')), 'ValueWas3', 'NotSpecified', $value)) 
    return 
} 

деталей все технологические , сообщая об ошибке на третьем:

1 
2 
Do-Something : $value was 3 
At C:\Users\Me\Desktop\Untitled1.ps1:58 char:9 
+ 1..10 | Do-Something 
+   ~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [Write-Error], WriteErrorException 
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException 
    ,Do-Something 

4 
5 
6 
7 
8 
9 
10 

Правильно ли я должен иметь дело с проблемами с конвейерными объектами, или я должен смотреть на структуру моих функций?

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

Причина, по которой я хочу, чтобы что-то вроде этого было в блоке функции end, я иногда могу сообщить о том, какие элементы были успешно обработаны и что не удалось (возможно, по какой-либо причине).

+0

Возможно, вам стоит больше ознакомиться с обработкой execption [C# MSDN Exceptions and Exception Handling] (https://msdn.microsoft.com/en-us/library/ms173160.aspx) – MethodMan

+0

Я знаю, как обрабатывать исключения, I «Мне просто интересно, как я собираюсь разрешить обрабатывающие элементы обрабатывать, так как перестройка исключения заставляет конвейер останавливаться, а остальные элементы не обрабатываются. – Jake

+2

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

ответ

2

При написании команды PowerShell у вас есть две широкие возможности для выражения ошибок: non-terminating и terminating ошибок.

Ошибка non-terminating, если команда может быть продолжена. Например, вы копируете 1000 файлов, а первый заблокирован. Нет смысла полностью проваливать всю операцию. В этом случае достаточно использовать Write-Error и записать информацию об ошибке в поток ошибок для этого файла и перейти к копированию других файлов.

Используйте ошибку terminating, если вы столкнулись с ошибкой, в которой вы просто не можете продолжить. Например, если первым шагом вашей команды является установление соединения с удаленной службой, и служба не отвечает, вы не можете продолжать работу. В случае с завершающей ошибкой ваши варианты: A) throw, B) использовать ThrowTerminatingError() или C), чтобы исключить исключение из реализации вашей команды. Это вариации исключения (или не ловушки) исключения.

BTW независимо от того, используете ли вы оператор return после того, как Write-Error зависит от того, хотите ли вы выполнить какой-либо код (возможно, код очистки) для текущего объекта конвейера.

Смежные вопросы