概要: このチュートリアルでは、Promiseにおけるエラー処理の方法を学びます。
getUserById() というPromiseを返す関数があると仮定します。
function getUserById(id) {
return new Promise((resolve, reject) => {
resolve({
id: id,
username: 'admin'
});
});
}Code language: JavaScript (javascript)通常のエラー
まず、getUserById()関数を、Promiseの外部でエラーをスローするように変更します。
function getUserById(id) {
if (typeof id !== 'number' || id <= 0) {
throw new Error('Invalid id argument');
}
return new Promise((resolve, reject) => {
resolve({
id: id,
username: 'admin'
});
});
}Code language: JavaScript (javascript)次に、then()とcatch()メソッドの両方を使用してPromiseを処理します。
getUserById('a')
.then(user => console.log(user.username))
.catch(err => console.log(err));Code language: JavaScript (javascript)コードがエラーをスローする
Uncaught Error: Invalid id argumentCode language: JavaScript (javascript)Promiseの外部で例外を発生させる場合は、try/catchでキャッチする必要があります。
try {
getUserById('a')
.then(user => console.log(user.username))
.catch(err => console.log(`Caught by .catch ${err}`));
} catch (error) {
console.log(`Caught by try/catch ${error}`);
}Code language: JavaScript (javascript)出力
Caught by try/catch Error: Invalid id argumentCode language: JavaScript (javascript)Promise内部のエラー
getUserById()関数をPromise内部でエラーをスローするように変更します。
let authorized = false;
function getUserById(id) {
return new Promise((resolve, reject) => {
if (!authorized) {
throw new Error('Unauthorized access to the user data');
}
resolve({
id: id,
username: 'admin'
});
});
}Code language: JavaScript (javascript)そして、Promiseを消費します。
try {
getUserById(10)
.then(user => console.log(user.username))
.catch(err => console.log(`Caught by .catch ${err}`));
} catch (error) {
console.log(`Caught by try/catch ${error}`);
}Code language: JavaScript (javascript)出力
Caught by .catch Error: Unauthorized access to the user dataCode language: JavaScript (javascript)Promise内部でエラーをスローすると、try/catchではなくcatch()メソッドがそれをキャッチします。
Promiseをチェーンする場合、catch()メソッドは、どのPromiseで発生したエラーでもキャッチします。例えば
promise1
.then(promise2)
.then(promise3)
.then(promise4)
.catch(err => console.log(err));
Code language: JavaScript (javascript)この例では、promise1、promise2、またはpromise4でエラーが発生した場合、catch()メソッドがそれを処理します。
reject()関数の呼び出し
エラーをスローすることは、次の例に示すように、reject()を呼び出すのと同じ効果があります。
let authorized = false;
function getUserById(id) {
return new Promise((resolve, reject) => {
if (!authorized) {
reject('Unauthorized access to the user data');
}
resolve({
id: id,
username: 'admin'
});
});
}
try {
getUserById(10)
.then(user => console.log(user.username))
.catch(err => console.log(`Caught by .catch ${err}`));
} catch (error) {
console.log(`Caught by try/catch ${error}`);
}
Code language: JavaScript (javascript)この例では、Promise内部でエラーをスローする代わりに、明示的にreject()を呼び出しました。この場合も、catch()メソッドがエラーを処理します。
catch()メソッドの欠落
次の例では、Promise内部のエラーを処理するためのcatch()メソッドが提供されていません。これにより、ランタイムエラーが発生し、プログラムが終了します。
function getUserById(id) {
return new Promise((resolve, reject) => {
if (!authorized) {
reject('Unauthorized access to the user data');
}
resolve({
id: id,
username: 'admin'
});
});
}
try {
getUserById(10)
.then(user => console.log(user.username));
// the following code will not execute
console.log('next');
} catch (error) {
console.log(`Caught by try/catch ${error}`);
}Code language: JavaScript (javascript)出力
Uncaught (in promise) Unauthorized access to the user dataPromiseが解決される場合、catch()メソッドを省略できます。 将来、潜在的なエラーが発生すると、プログラムが予期せず停止する可能性があります。
まとめ
- Promise内部では、
catch()メソッドがthrowステートメントとreject()によって引き起こされたエラーをキャッチします。 - エラーが発生し、
catch()メソッドがない場合、JavaScriptエンジンはランタイムエラーを発行し、プログラムを停止します。