例外をキャッチする構文

Java、Scala、JavaScript、CoffeeScript、PHP、C++、Perl、Ruby、Pythonでの例外をキャッチする構文。

Java

try {
  ...;
} catch (FileNotFoundException e) {
  ...;
} catch (IOException e) {
  ...;
} finally {
  ...;
}

Java7から使える try-with-resources 構文では以下のように書ける。finally節を書かなくても try のカッコの中で生成したオブジェクトを確実にcloseしてくれる。この構文ではcatch節も書かずにtryのみも可能。

try (FileInputStream in = new FileInputStream(...)) {
  ...;
} catch (FileNotFoundException e) {
  ...;
} catch (IOException e) {
  ...;
}

同じくJava7からの機能では、catch節のカッコの中に複数の例外クラスを書ける。

try {
  ...;
} catch (IllegalArgumentException | IOException e) {
  ...;
}

IOException | FileNotFoundException のような一方が他方に含まれるような書き方はできないし、意味がない。

Java7から例外を再スローするときの型推論が改善されている。

Scala

try {
  ...;
} catch {
  case e: IOException =>
    ...;
  case e: FileNotFoundException =>
    ...;
  case _: Exception => // 例外オブジェクトを変数で捕捉する必要がない場合
    ...;
  case e => // 例外オブジェクトの型を問わない場合
    ...;
} finally {
  ...;
}

try式は式なので、値を返す。try節の中から例外がスローされなかった場合は、finally節の中を実行した後にtry節の中の最後の式の値がtry式全体の返り値になる。

catch節の書き方はmatchと同じ。

JavaScript

try {
  ...;
} catch(ex) {
  ...;
} finally {
  ...;
}

CoffeeScript

try
  ...
catch ex
  ...
finally
  ...

PHP

try {
    ...;
} catch (Exception $e) {
    ...;
} catch (FooException | BarException $e) { // 複数の例外クラスをまとめてキャッチ
    ...;
} finally {
    ...;
}

finally節が書けるのはPHP 5.5以降。

複数の例外クラスをまとめてキャッチできるのはPHP 7.1以降。

PHP: Exceptions - Manual

C++

try {
  ...;
} catch (FooClass e) {
  ...;
} catch (BarClass e) {
  ...;
}

Perl

eval {
    ...;
};
if ($@) {
    # 例外が発生した場合の処理
    ...;
}

guardまたはscope_guardを使えば、他の言語のfinallyに相当することができる。

Scope::Guard - レキシカルスコープにおけるリソース管理 - perldoc.jp

Ruby

begin
  ...
rescue
  ...
else
  ...
ensure
  ...
end

rescue節で例外オブジェクトを利用したい場合は、以下のように書く。

rescue => e

エラーメッセージは、 e.message で取得できる。

スタックトレースを出力するには print e.backtrace.join("\n") と書く。

rescue節で特定のクラスの例外だけを捕捉したい場合は、以下のように書く。

rescue ZeroDivisionError => e

例外クラス名はコンマ区切りで複数書ける。

捕捉する例外クラスのクラス名を省略すると、 StandardError を捕捉するとみなされるので、StandardError 以外の Exception のインスタンスは捕捉されない。

rescue節自体は複数書くことができる。

rescue節の中では retry と書くと、beginからやりなおしてくれる。これは他の言語にはあまりない機能である。

else節は例外が発生しなかった場合にensure節の前に実行される。これも他の言語にはあまりない機能である。

Python

try:
  ...
except:
  ...
else:
  ...
finally:
  ...

except節で特定の例外クラスだけを捕捉したい場合は、次のように書く。

except HogeException:

except節で複数の例外クラスだけを捕捉したい場合は、次のように書く。

except (HogeException, PiyoException):

except節で例外インスタンスを捕捉したい場合は、次のように書く。

except HogeException as ex:

except節の中で同じ例外を再スローするには単に

raise

とだけ書く。

else節はtry節で例外がスローされずに完了した場合に実行される。例外がスローされた場合はexcept節でキャッチされたかどうかに関わらずelse節は実行されない。

finally節は例外がスローされてもされなくても最後に必ず実行される。finally節の前にreturnbreakcontinueで脱出しようとしたときにも脱出直前に実行される。

8. Errors and Exceptions — Python 3.9.1 documentation

このサイトは個人メモの集合です。
スポンサーリンク