aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/javascript/reference/statements/try...catch/index.md
blob: 0cdc875f9d8b75eea3416e349bc5917ea4074d1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
---
title: try...catch
slug: Web/JavaScript/Reference/Statements/try...catch
tags:
  - 例外
  - JavaScript
  - 言語機能
  - 文
browser-compat: javascript.statements.try_catch
translation_of: Web/JavaScript/Reference/Statements/try...catch
---
{{jsSidebar("Statements")}}

**`try...catch`** 文は、試す文のブロックをマークし、例外が発生したときの応答を指定します。

{{EmbedInteractiveExample("pages/js/statement-trycatch.html")}}

## 構文

```js
try {
  try_statements
}
catch (exception_var) {
  catch_statements
}
finally {
  finally_statements
}
```

- `try_statements`
  - : 実行される文です。
- `catch_statements`
  - : `try` ブロックの中で例外が発生した場合に実行される文です。
- `exception_var`
  - : 関連する `catch` 節に対して例外オブジェクトを保持する識別子です。
- `finally_statements`
  - : `try` 文が完了した後に実行される文です。これらの文は、例外が発生されたり捕捉されたりしたかどうかに関係なく実行されます。

## 解説

`try` 文は、1 つ以上の文を含む `try` ブロックにより構成されます。文が 1 つであっても、常に `{}` を使用する必要があります。1 つ以上の `catch` ブロック、または `finally` ブロックが存在する必要があります。すなわち、`try` 文には 3 つの形態があります。

- `try...catch`
- `try...finally`
- `try...catch...finally`

`catch` ブロックは、例外が `try` ブロックの中で発生した場合に何をするかを指定する文を含みます。`try` ブロック内 (または `try` ブロック内から呼び出された関数の中) のいずれかの文で例外が発生した場合は、制御は即座に `catch` ブロックへ移ります。`try` ブロックの中で例外が発生しなかった場合は、`catch` ブロックは飛ばされます。

`finally` ブロックは、`try` ブロックおよび `catch` ブロックの実行が完了した後で実行されます。これは常に実行され、例外が発生したかどうか、捕捉されたかどうかには関係ありません。

1 つ以上の `try` 文を入れ子にする事ができます。内側の `try` 文が `catch` ブロックを持っていない場合、それを囲んでいる `try` 文の `catch` ブロックに入ります。

`try` を使用して JavaScript の例外を処理することもできます。 JavaScript の例外に関する情報は [JavaScript ガイド](/ja/docs/Web/JavaScript/Guide)を参照してください。

### 無条件の catch ブロック

`catch` ブロックが使われている場合、`try` ブロックの中から任意の例外が発生すると、`catch` ブロックが実行されます。例えば、以下のコードで例外が発生すると、制御は `catch` ブロックへ移動します。

```js
try {
  throw 'myException'; // 例外を生成
} catch (e) {
  // 任意の例外を操作するための文
  logMyErrors(e); // エラーハンドラーに例外オブジェクトを渡します
}
```

`catch` ブロックは例外の値を保持する識別子 (上記の例では `e`) を指定します。この値は `catch` ブロックの{{Glossary("Scope", "スコープ")}}内でのみ利用できます。

### 条件付き catch ブロック

「条件付き `catch` ブロック」は、下記のように `try...catch` ブロックを `if...else if...else` 構造と組み合わせることで作成することができます。

```js
try {
  myroutine(); // 3 つの例外が発生する可能性があります
} catch (e) {
  if (e instanceof TypeError) {
    // TypeError 例外を処理するための文
  } else if (e instanceof RangeError) {
    // RangeError 例外を処理するための文
  } else if (e instanceof EvalError) {
    // EvalError 例外を処理するための文
  } else {
    // 任意の指定されていない例外を操作するための文
    logMyErrors(e); // エラーハンドラーに例外オブジェクトを渡す
  }
}
```

よくある使用例としては、次のように想定済みの一部のエラーのみを捕捉 (および無視) し、それ以外の場合はエラーを送出し直す場合です。

```js
try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // 頻発する想定済みのエラーを処理する文
  } else {
    throw e;  // エラーを変更しないまま送出し直す
  }
}
```

### 例外識別子

例外が `try` ブロックの中で発生したときは、_`exception_var`_ (たとえば、`catch (e)` における `e`) が例外の値を保持します。この識別子を使用して、発生した例外についての情報を取得することができます。この識別子は `catch` ブロックの{{Glossary("Scope", "スコープ")}}でのみ利用できます。例外の値が必要ない場合にはこれは省略できます。

```js
function isValidJSON(text) {
  try {
    JSON.parse(text);
    return true;
  } catch {
    return false;
  }
}
```

### finally ブロック

`finally` ブロックには、`try` ブロックおよび `catch` ブロックを実行した後で、`try...catch...finally` の次の文が実行される前に実行される文が入ります。なお、`finally` ブロックは例外が発生するかどうかにかかわらず実行されます。また、例外が発生した場合、`finally` ブロックは例外を処理する `catch` ブロックがなくても実行されます。

次の例では `finally` ブロックの一つの使用例を示します。このコードはファイルを開き、それからファイルを使用する分を実行します。`finally` ブロックは、例外が発生したとしてもその後で確実にファイルを閉じるよう保証します。

```js
openMyFile();
try {
  // リソースを結び付けます
  writeMyFile(theData);
} finally {
  closeMyFile(); // リソースを常に閉じます
}
```

## 例

### 入れ子になった try ブロック

最初に、次のもので何が起きるか見てみましょう。

```js
try {
  try {
    throw new Error('oops');
  } finally {
    console.log('finally');
  }
} catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "finally"
// "outer" "oops"
```

ここで、既に内部の `try` ブロックに `catch` ブロックを追加しているので、既に例外を捕捉しています。

```js
try {
  try {
    throw new Error('oops');
  } catch (ex) {
    console.error('inner', ex.message);
  } finally {
    console.log('finally');
  }
} catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"
```

そして、エラーを送りなおします。

```js
try {
  try {
    throw new Error('oops');
  } catch (ex) {
    console.error('inner', ex.message);
    throw ex;
  } finally {
    console.log('finally');
  }
} catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"
// "outer" "oops"
```

送り直されない限り、例外はどれでも最も内側の `catch` ブロックで一度だけ捕捉されます。もちろん、何らかの例外が「内側の」のブロックで発生した場合 (`catch` ブロックのコードで例外が発生することを行った場合)、「外側の」ブロックで捕捉されます。

### finally ブロックからの return

`finally` ブロックが値を返す場合、その値が `try-catch-finally` 全体の返値になり、 `try` ブロックや `catch` ブロックの `return` 文に関係なくなります。
これは `catch` ブロック内で例外が発生した場合も含まれます。

```js
(function() {
  try {
    try {
      throw new Error('oops');
    } catch (ex) {
      console.error('inner', ex.message);
      throw ex;
    } finally {
      console.log('finally');
      return;
    }
  } catch (ex) {
    console.error('outer', ex.message);
  }
})();

// 出力結果:
// "inner" "oops"
// "finally"
```

外側の "oops" は `finally` ブロックに return があるため送出されません。同じことが、`catch` ブロックから返されているそのほかの値にも適用されます。

## 仕様書

{{Specifications}}

## ブラウザーの互換性

{{Compat}}

## 関連情報

- {{jsxref("Error")}}
- {{jsxref("Statements/throw", "throw")}}