PowerShell `throw` 키워드

PowerShell throw 키워드 (about_Throw)

스크립트를 짜다 보면 “여기서는 더 진행하면 안 되겠다” 싶은 순간이 생겨요. 그럴 때 throw 키워드가 큰 역할을 해요. 기본적으로 스크립트를 중단시키는 종료(script-terminating) 오류를 던져서, 흐름을 딱 거기서 멈추게 하는 거죠. 이 문서에서는 throw가 정확히 어떻게 동작하는지, 어떤 상황에서 어떻게 쓰면 좋은지를 하나씩 살펴볼게요.

출처: about_Throw - PowerShell | Microsoft Learn

본문

간단한 설명 (Short description)

throw 키워드를 설명하는 문서예요. 기본적으로 스크립트를 종료시키는(script-terminating) 오류를 만들어내죠.

자세한 설명 (Long description)

throw 키워드는 기본적으로 스크립트 종료 오류를 일으켜요. 명령(command), 함수(function), 스크립트(script)의 처리를 여기서 멈추는 데 쓸 수 있어요.

문(statement) 종료 오류와 달리, throw 키워드는 호출 스택(call stack) 전체를 풀어버려요. try/catch 블록이나 trap 문으로 오류를 잡아주지 않으면 실행이 완전히 멈춰버리죠.

참고

$ErrorActionPreferencethrow를 억제할 수 있어요. SilentlyContinueIgnore로 설정하면 오류가 전파되지 않고, 실행은 다음 문에서 이어져요. 고급 함수(advanced function)를 -ErrorAction SilentlyContinue로 호출하면 그 매개변수가 함수 범위 안의 $ErrorActionPreference 값으로 변환되기 때문에, 함수 안의 throw도 함께 억제돼요. 그래도 throw는 여전히 $Error에 항목을 기록해요. Ignore 값은 $PSCmdlet.ThrowTerminatingError()가 만들어내는 것 같은 비종료(non-terminating) 오류가 $Error에 기록되는 것만 막아줘요.

오류 범주와 $ErrorActionPreference 동작에 대해 더 알고 싶다면 about_Error_Handling을 확인하세요.

예를 들어 if 문의 문 블록에서 어떤 조건에 응답하거나, try/catch/finally 문의 catch 블록 안에서 쓰는 식으로 throw 키워드를 활용할 수 있어요. 사용자 메시지 문자열처럼 어떤 객체든 던질 수 있고요.

문법 (Syntax)

throw 키워드의 문법은 다음과 같아요.

throw [<expression>]

throw 문법에서 expression은 선택이에요. throw 문이 catch 블록 밖에 있고 표현식도 포함하지 않으면 ScriptHalted 오류를 만들어내요.

throw
Exception: ScriptHalted

catch 블록 안에서 표현식 없이 throw 키워드를 쓰면 현재의 RuntimeException을 다시 던져요. 자세한 내용은 about_Try_Catch_Finally를 보면 돼요.

문자열 던지기 (Throwing a string)

throw 문의 선택 표현식은 문자열이 될 수 있는데, 다음 예시처럼요.

throw "This is an error."
Exception: This is an error.

다른 객체 던지기 (Throwing other objects)

표현식은 객체일 수도 있어요. 다음 예시는 PowerShell 프로세스를 나타내는 객체를 던지는데, 실제로 어떤 결과가 나오는지 볼게요.

throw (Get-Process pwsh)
Exception: System.Diagnostics.Process (pwsh) System.Diagnostics.Process (pwsh) System.Diagnostics.Process (pwsh)

$Error 자동 변수에 들어 있는 ErrorRecord 객체의 TargetObject 속성으로 오류를 자세히 살펴볼 수 있어요.

$Error[0].TargetObject
 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
    125   174.44     229.57      23.61    1548   2 pwsh
     63    44.07      81.95       1.75    1732   2 pwsh
     63    43.32      77.65       1.48    9092   2 pwsh

ErrorRecord 객체나 .NET 예외도 던질 수 있어요. 다음 예시는 throw 키워드로 System.FormatException 객체를 던져요.

$formatError = New-Object System.FormatException
throw $formatError
OperationStopped: One of the identified items was in an invalid format.

결과로 만들어지는 오류 (The resulting error)

throw 키워드는 ErrorRecord 객체를 만들어낼 수 있어요. ErrorRecord 객체의 Exception 속성에는 RuntimeException 객체가 담겨 있죠. 나머지 ErrorRecord 객체와 RuntimeException 객체는 던져진 객체가 무엇인지에 따라 달라져요.

throw로 던지는 객체는 ErrorRecord 객체로 감싸지고, 그 ErrorRecord 객체는 자동으로 $Error 자동 변수에 저장돼요.

필수 매개변수를 만들 때 throw 쓰기 (Using throw to create a mandatory parameter)

과거 PowerShell 버전과 달리, 매개변수 검증에는 throw 키워드를 쓰지 마세요. 올바른 방법은 about_Functions_Advanced_Parameters를 확인하면 돼요.

더 알아보기