Function Compute は、Node.js 関数がスローしたエラーをキャッチし、構造化されたレスポンスを返します。このページでは、Node.js 関数が生成する 2 つのエラーカテゴリと、サービスから返される HTTP ステータスコードの解釈方法について説明します。
エラーの種類
キャッチされた例外
関数が例外をスローすると、Function Compute はそれをキャッチし、次の 3 つのフィールドを含む JSON オブジェクトを返します。
| フィールド | 説明 |
|---|---|
errorMessage |
エラーメッセージ文字列 |
errorType |
JavaScript エラークラス名 |
stackTrace |
スタックフレームの配列 |
ECMAScript モジュール
ECMAScript モジュール構文には Node.js 18 以降が必要です。サンプルコードはワンクリックデプロイに対応しています (nodejs-fc-err-es)。export const handler = async (event, context) => {
throw new Error('oops');
};
CommonJS モジュール
exports.handler = function(event, context, callback) {
throw new Error('oops');
};
レスポンスの例:
{
"errorMessage": "oops",
"errorType": "Error",
"stackTrace": [
"Error: oops",
" at handler (file:///code/index.mjs:2:9)",
" at module.exports (file:///var/fc/runtime/nodejs20/bootstrap.mjs:5655:14)",
" at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"
]
}
異常終了
関数の実行中に process.exit() が呼び出されると、ランタイムは構造化されたエラーをキャッチできません。サービスは代わりに汎用メッセージを返します。
ECMAScript モジュール
ECMAScript モジュール構文には Node.js 18 以降が必要です。
export const handler = async (event, context) => {
process.exit(1);
};
CommonJS モジュール
exports.handler = function(event, context, callback) {
process.exit(1);
};
レスポンスの例:
{
"errorMessage": "Process exited unexpectedly before completing request (duration: 12ms, maxMemoryUsage: 0MB)"
}
HTTP ステータスコード
2xx レスポンスは、関数が成功したことを保証するものではありません。2xx ステータスコードで返される関数のエラーを検出するには、X-Fc-Error-Type レスポンスヘッダーを確認してください。
関数呼び出しが失敗すると、Function Compute は HTTP ステータスコード、レスポンスボディ、および、関数レベルのエラーについては X-Fc-Error-Type レスポンスヘッダーを返します。これらの情報を確認して、コードでエラーを処理するか、エンドユーザーに表示します。
| ステータスコード | 意味 |
|---|---|
| 2xx | X-Fc-Error-TypeFunction Compute がリクエストを受信しました。レスポンスに ヘッダーが含まれている場合、関数エラーが発生しています (例:コード内のキャッチされなかった例外)。 |
| 4xx (429 を除く) | 呼び出し元のクライアントが無効なリクエストを送信しました。 |
| 429 | リクエストがスロットリングされました。 |
| 5xx | Function Compute で内部エラーが発生したか、関数設定が無効であるか、リソースに問題があります。 |
呼び出しエラーの詳細については、「再試行メカニズムの設定」をご参照ください。
よくある質問
require is not defined in ES module scope
現象
ES モジュール (ファイル拡張子が .mjs、または package.json で "type": "module" が設定されている) としてロードされる Node.js 関数のエントリーファイルで、require() を使用してモジュールをロードすると、呼び出しは HTTP ステータスコード 200 を返しますが、レスポンスヘッダーには X-Fc-Error-Type: InvocationError が含まれ、レスポンスボディには次のエラーが含まれます:
{
"errorMessage": "require is not defined in ES module scope, you can use import instead",
"errorType": "ReferenceError",
"stackTrace": [
"ReferenceError: require is not defined in ES module scope, you can use import instead",
" at file:///code/index.mjs:1:15",
" at ModuleJob.run (node:internal/modules/esm/module_job:218:25)"
]
}
エラー内容は、エントリファイルのタイプと require() の場所によって異なります:
-
エントリファイルの拡張子が
.jsで、package.jsonで"type": "module"が設定されている場合、errorMessageには次の行が追加されます。このファイルは、ファイル拡張子が '.js' であり、'/code/package.json' に "type": "module" が含まれているため、ES モジュールとして扱われています。CommonJS スクリプトとして扱うには、ファイル拡張子を '.cjs' に変更してください。 -
モジュールのトップレベルではなくハンドラー関数の内部で
require()が呼び出された場合、errorMessageはrequire is not definedになります。
原因
require() は CommonJS モジュールシステムの読み込み関数であり、ES モジュールスコープでは利用できません。ファイルが ES モジュールとして識別されると、Node.js は require、module、exports などの CommonJS 変数を注入しません。
ソリューション
コード構造に応じて、次のいずれかの方法を選択してください。
-
require()を ES モジュールimport文に書き換えます。モジュールを動的にロードするには、import()式を使用します。 -
require()構文を維持するには、エントリファイルの拡張子を.cjsに変更します。関数ハンドラーの設定を変更する必要はありません。
以下に ES モジュールの書き換え (エントリファイル index.mjs) の例を示します。
// Node.js の組み込みモジュールとローカルの ES モジュールファイルをインポートします
import { createHash } from 'node:crypto';
import { helper } from './utils.mjs';
export const handler = async (event, context) => {
return createHash('sha256').update(helper()).digest('hex');
};
次の例は、モジュールを動的に読み込む方法を示しています。
const crypto = await import('node:crypto');
以下に CommonJS 構文 (エントリーファイル index.cjs) の例を示します。
const crypto = require('crypto');
exports.handler = async (event, context) => {
return crypto.createHash('sha256').digest('hex');
};
注: サードパーティ依存関係 (lodashなど) をロードするには、まずローカルでnpm installを実行してから、node_modulesディレクトリをコードと共にパッケージ化してデプロイします。ES モジュールでは、たとえばimport _ from 'lodash';のように、デフォルトインポートを使用して CommonJS 依存関係を参照できます。
ES モジュールは、Node.js 18 以降のランタイムでのみサポートされています。Node.js 16 以前のランタイムでは、.mjs エントリファイルはロードされず、呼び出しによって "errorMessage": "Module '/code/index.js' is missing." および "errorType": "FunctionUnhandledError: ImportModuleError" が返されます。