throw文

【連載】

PowerShell Core入門 - 基本コマンドの使い方

【第35回】throw文

[2019/01/18 16:27]後藤大地 ブックマーク ブックマーク

  • サーバ/ストレージ

サーバ/ストレージ

終了エラーを発生させるthrow

前回、いわゆる例外処理を行うためのtry-catch制御構文を紹介した。try-catch制御構文を利用することで、try {}ブロックの中で発生するエラーを捕捉し、catch {}やfinally {}で後始末を行うことができることを示した。これに関連する機能として今回はthrow文を取り上げようと思う。

try-catch制御構文はオブジェクト指向のプログラミング言語など、比較的若い最近のプログラミング言語には組み込まれていることが多い。try-catch制御構文を使う場合、いろいろな例外処理をcatch {}やfinally {}の方で処理したくなるが、そんな場合に使えるのがthrow文だ。

throwを実行すると、その場で終了エラーを発生させることができる。throwによって発生させられるエラーはtry-catch制御構文の捕捉の対象となる。明示的にエラーを発生させたい場合にはこの機能を使うことになる。

throwの基本的な使い方

throwの基本的な使い方は次のとおり。throwは引数に何も指定しなくてもよいし、式を書いてもよい。

throwのもっともシンプルな使い方

throw

例えばPowerShell Coreのインタラクティブ状態でthrowを実行すると次のような結果が得られる。ScriptHaltedエラーが生成されていることがわかる。

引数なしでthrowを実行してScriptHaltedエラーが発生していることを確認

PS /Users/daichi> throw
ScriptHalted
At line:1 char:1
+ throw
+ ~~~~~
+ CategoryInfo          : OperationStopped: (:) [], RuntimeException
+ FullyQualifiedErrorId : ScriptHalted

PS /Users/daichi>

throw文には引数としてエラーメッセージを指定することができる。

throwにメッセージを指定して実行

throw "エラーメッセージ"

次のようにエラーメッセージを指定してthrow文を実行することで、エラーメッセージが認識されていることを確認できる。

throwにエラーメッセージを指定して実行した場合のサンプル

PS /Users/daichi> throw "エラーメッセージ"
エラーメッセージ
At line:1 char:1
+ throw "エラーメッセージ"
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (エラーメッセージ:String) [], RuntimeException
+ FullyQualifiedErrorId : エラーメッセージ

PS /Users/daichi>

throwにはテキストだけではなくオブジェクトを指定することもできる。例えば次のような使い方をすればプロセス情報が引数としてthrowで使われることになる。

throwの引数にはオブジェクトを指定することもできる

throw (Get-Process pwsh)

例えば上記を実際に実行してみると、次のようにSystem.Diagnostics.Processオブジェクトがわたされていることを確認できる。$error[0].targetobjectにGet-Process pwshの結果が入っていることも確認できる。

PS /Users/daichi> Get-Process pwsh      

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00      93.53     263.18   45719 703 pwsh


PS /Users/daichi> throw (Get-Process pwsh)
System.Diagnostics.Process (pwsh)
At line:1 char:1
+ throw (Get-Process pwsh)
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (System.Diagnostics.Process (pwsh):Process) [], RuntimeException
+ FullyQualifiedErrorId : System.Diagnostics.Process (pwsh)

PS /Users/daichi> $error[0].targetobject

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00      95.52     270.43   45719 703 pwsh


PS /Users/daichi>

try-catchとthrowの動作を知る

前回はtry-catch制御構文を紹介したが、エラーが発生した場合にどのように処理が流れていくかを把握しておくことが大切だということがおわかりいただけただろう。try-catch制御構文とthrowを使う場合、どのように処理が流れていくのかを知っておくことが大切だ。

まず、次のようにtry {}の中でthrowを実行してみる。

try {}の中でthrowを実行する

try
{
    "tryに入りました"
    throw "try内で終了エラーを発生"
} catch {
    "catchに入りました"
} finally {
    "finallyに入りました"
}

実行すると次のようにtry→エラー発生→catch→finallyと処理が流れていることがわかる。明示的にエラーを発生させただけで、前回紹介したtry-catch制御構文通りの動きが起こっていることがわかる。

try {}の中でthrowを実行させたサンプル

PS /Users/daichi> try
>> {
>> "tryに入りました"
>> throw "try内で終了エラーを発生"
>> } catch {
>> "catchに入りました"
>> } finally {
>> "finallyに入りました"
>> }
tryに入りました
catchに入りました
finallyに入りました
PS /Users/daichi>

次に、catchの中でもthrowを実行するケースを考えてみる。

catch {}の中でもthrowを実行してみる

try
{
    "tryに入りました"
    throw "try内で終了エラーを発生"
} catch {
    "catchに入りました"
    throw "catch内で終了エラーを発生"
} finally {
    "finallyに入りました"
}

実行すると次のようになる。catch {}でthrowが実行されると、先にfinally {}を処理した上でthrowの内容が処理されていることがわかる。

catch {}の中でthrowを実行すると、finallyを処理した上でthrowが処理されることがわかる

PS /Users/daichi> try
>> {
>> "tryに入りました"
>> throw "try内で終了エラーを発生"
>> } catch {
>> "catchに入りました"
>> throw "catch内で終了エラーを発生"
>> } finally {
>> "finallyに入りました"
>> }
tryに入りました
catchに入りました
finallyに入りました
catch内で終了エラーを発生
At line:7 char:1
+ throw "catch内で終了エラーを発生"
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (catch内で終了エラーを発生:String) [], RuntimeException
+ FullyQualifiedErrorId : catch内で終了エラーを発生

PS /Users/daichi>

それではさらにfinally {}の中でもthrowを実行させてみよう。

finally {}の中でもthrowを実行してみる

try
{
    "tryに入りました"
    throw "try内で終了エラーを発生"
} catch {
    "catchに入りました"
    throw "catch内で終了エラーを発生"
} finally {
    "finallyに入りました"
    throw "finally内で終了エラーを発生"
}

実行すると次のようになる。どうやらcatch {}の中のthrowが実行され処理がfinally {}に移り、finally {}の中のthrowに到達するとこのthrowが実行されて処理が終わるようだ。catch {}の中のthrowには処理は戻っていないことがわかる。

PS /Users/daichi> try
>> {
>> "tryに入りました"
>> throw "try内で終了エラーを発生"
>> } catch {
>> "catchに入りました"
>> throw "catch内で終了エラーを発生"
>> } finally {
>> "finallyに入りました"
>> throw "finally内で終了エラーを発生"
>> }
tryに入りました
catchに入りました
finallyに入りました
finally内で終了エラーを発生
At line:10 char:1
+ throw "finally内で終了エラーを発生"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (finally内で終了エラーを発生:String) [], RuntimeException
+ FullyQualifiedErrorId : finally内で終了エラーを発生

PS /Users/daichi>

try-catch制御構文を活用してエラー処理をしようとした場合、このあたりのフローを把握していくことが大切だ。ここでthrowを実行すればここに処理が飛ぶはずだ、と思い込んでいると、実はそこには処理は飛ばないといったことが起こりかねないからだ。

try-catch制御構文かif制御構文か

try-catch制御構文を使うか、if制御構文を使ってエラーが発生する前または発生した後に処理を切り分けていくかは、なかなかどちらがよいか難しいところがある。プログラミング言語によってはtry-catchの方を使うしか方法がないこともあるし、逆にtry-catchの機能が提供されていないのですべてif制御構文で判断しながら処理していかなければならないこともある。

どちらを使うかは書き手の好みの問題もあるのでなんとも言えないのだが、少なくとも他人が書いたコードが読めるようにtry-catch制御構文とthrowの関係を知っておく必要はあるだろう。

参考資料

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】RPA入門 - ツールで学ぶ活用シーン

【連載】RPA入門 - ツールで学ぶ活用シーン

AIには、ルールベース、機械学習、深層学習(ディープラーニング)の3つのレベルがあり、レベルが上がるに連れてより高度な人工知能を実現しますが、AIのスピンオフという位置付けで、Digital Labor(仮想知的労働者)によるホワイトカラー業務の自動化を実現するRPAが注目されています。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします

会員登録(無料)

注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
[解説動画] 個人の業務効率化術 - 短時間集中はこうして作る
知りたい! カナコさん 皆で話そうAIのコト
教えてカナコさん! これならわかるAI入門
対話システムをつくろう! Python超入門
Kubernetes入門
AWSで作るクラウドネイティブアプリケーションの基本
PowerShell Core入門
徹底研究! ハイブリッドクラウド
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

ページの先頭に戻る