デバッグとトラブルシューティング
kintone の JavaScript カスタマイズを開発していると、コードが期待どおりに動かない場面に必ず遭遇します。変数の値が想定と異なる、API のレスポンスがエラーになる、イベントが発火しないなど、その原因はさまざまです。
しかし、デバッグの基本的な手法を身につけておけば、多くの問題を効率的に特定・解決できます。
この記事では、kintone カスタマイズの開発で頻繁に使うデバッグ手法と、よくあるエラーの原因・対処法をまとめて紹介します。
Chrome DevTools の基本
kintone のカスタマイズをデバッグする際、最も基本的なツールはブラウザの開発者ツール(DevTools)です。Chrome の場合、F12 キーまたは Ctrl + Shift + I(Mac: Cmd + Option + I)で開くことができます。
Console タブ
Console タブは、JavaScript の実行結果やエラーメッセージを確認するための最も基本的なツールです。
(() => {
'use strict';
kintone.events.on(['app.record.detail.show'], (event) => {
// 基本的な値の確認
console.log('イベントオブジェクト:', event);
console.log('レコード:', event.record);
// 特定のフィールド値の確認
const title = event.record['タイトル'].value;
console.log('タイトル:', title);
return event;
});
})();
console.log だけでなく、目的に応じて console.table、console.group、console.time
を使い分けると、デバッグがより効率的になります。
console メソッドの使い分け
| メソッド | 用途 | 出力例 |
|---|---|---|
console.log | 汎用的なログ出力 | 変数の値、オブジェクトの中身 |
console.table | 配列やオブジェクトを表形式で表示 | サブテーブルの行データ、API レスポンスの一覧 |
console.dir | オブジェクトのプロパティを階層的に表示 | DOM 要素の詳細、event オブジェクトの構造 |
console.error | エラーとして目立つ形で出力 | catch ブロック内のエラー情報 |
console.warn | 警告として出力 | 非推奨な処理の検出、想定外の値の通知 |
console.group | ログをグループ化して折りたたみ表示 | 複数のフィールド値をまとめて確認 |
console.time | 処理時間の計測 | API 呼び出しのパフォーマンス確認 |
(() => {
'use strict';
kintone.events.on(['app.record.detail.show'], (event) => {
const record = event.record;
// テーブルデータを表形式で確認
const tableData = record['明細テーブル'].value.map((row) => ({
id: row.id,
商品名: row.value['商品名'].value,
数量: row.value['数量'].value,
}));
console.table(tableData);
// グループ化して情報を整理
console.group('レコード情報');
console.log('レコードID:', event.recordId);
console.log('アプリID:', kintone.app.getId());
console.log('ステータス:', record['ステータス']?.value);
console.groupEnd();
// API呼び出しの処理時間を計測
console.time('API呼び出し');
// ... API呼び出し処理 ...
console.timeEnd('API呼び出し');
return event;
});
})();
Sources タブとブレークポイント
console.log を大量に書く代わりに、ブレークポイントを設定して処理を一時停止し、変数の値をリアルタイムで確認する方法もあります。
- DevTools の Sources タブを開く
Ctrl + P(Mac:Cmd + P)でファイル名を検索し、カスタマイズファイルを開く- 行番号をクリックしてブレークポイントを設定
- 対象のイベントを発火させる(ページ遷移、ボタンクリックなど)
- 処理がブレークポイントで一時停止し、変数の値を確認できる
コード中に debugger; と記述すると、DevTools
が開いている場合にその行で処理が一時停止します。Sources
タブでファイルを探す手間を省きたい場合に便利です。
(() => {
'use strict';
kintone.events.on(['app.record.edit.submit'], (event) => {
const record = event.record;
// ここで処理が一時停止する(DevToolsが開いている場合)
debugger;
// 一時停止した状態で、Consoleタブから record の値を確認できる
if (Number(record['金額'].value) > 100000) {
event.record['承認者'].disabled = false;
}
return event;
});
})();
Network タブ(API 通信のデバッグ)
REST API の呼び出しがうまくいかない場合は、Network タブでリクエストとレスポンスの内容を確認します。
- DevTools の Network タブを開く
- フィルターに
k/v1と入力して kintone API のリクエストだけに絞り込む - 対象の操作を実行する
- 表示されたリクエストをクリックして、以下を確認する:
- Headers: リクエストメソッド、URL、ステータスコード
- Payload: 送信したリクエストボディ
- Response: API からのレスポンス(エラーメッセージを含む)
Network タブの Preserve log にチェックを入れておくと、ページ遷移してもログが消えません。画面遷移を伴う処理(レコード保存後のリダイレクト等)のデバッグに役立ちます。
よくあるエラーと対処法
kintone カスタマイズでは、特定のパターンのエラーが頻繁に発生します。ここでは代表的なエラーとその対処法を紹介します。
TypeError: Cannot read properties of undefined
最も多いエラーの一つです。存在しないフィールドコードを参照した場合や、API レスポンスの構造を誤って解釈した場合に発生します。
// ❌ よくある間違い
const value = event.record['フィールドコード'].value;
// → フィールドコードが間違っている場合、TypeError が発生
// ✅ 安全な参照(ただし、根本原因の解決が優先)
const field = event.record['フィールドコード'];
if (!field) {
throw new Error('フィールド「フィールドコード」が見つかりません。フィールドコードを確認してください。');
}
const value = field.value;
event.record['フィールドコード']?.value
のようにオプショナルチェーンで回避するのは一時的な対策としては有効ですが、根本原因(フィールドコードの誤り等)を見落とす原因になります。エラーが出る場合は、まずフィールドコードが正しいか確認しましょう。
主な原因と対処法:
| 原因 | 対処法 |
|---|---|
| フィールドコードの誤り(全角/半角) | アプリ設定 → フォーム画面でフィールドコードを正確にコピー |
| テーブル内フィールドの参照ミス | row.value['フィールドコード'] の形式で参照する |
| API レスポンスの構造の誤解 | console.log でレスポンス全体を出力して構造を確認 |
| イベントオブジェクトに存在しない属性 | 公式ドキュメントで event オブジェクトの仕様を確認 |
kintone.api の 520 エラー
kintone 独自のエラーコードで、主にリクエストの形式に問題がある場合に返されます。
// ❌ よくある間違い: パラメータの形式が不正
const body = {
app: kintone.app.getId(),
record: {
文字列フィールド: '値', // value プロパティが必要
},
};
// ✅ 正しいパラメータ形式
const body = {
app: kintone.app.getId(),
record: {
文字列フィールド: { value: '値' },
},
};
イベントが発火しない
カスタマイズのコードが実行されない場合、以下の点を確認します。
// ✅ チェックリスト
// 1. イベント名が正しいか
// 誤: 'app.record.details.show' (details → detail)
// 正: 'app.record.detail.show'
// 2. return event を忘れていないか
kintone.events.on(['app.record.edit.show'], (event) => {
// 処理...
return event; // ← これを忘れると後続の処理に影響
});
// 3. JavaScript ファイルが正しくアップロードされているか
// アプリの設定 → JavaScript / CSSでカスタマイズ → ファイルの順序を確認
// 4. 即時実行関数で囲んでいるか
// (() => { ... })(); の閉じ括弧が正しいか確認
イベント名のよくある間違い:
| 間違い | 正しいイベント名 |
|---|---|
app.record.details.show | app.record.detail.show |
app.record.edit.change | app.record.edit.change.フィールドコード |
app.record.index | app.record.index.show |
app.record.create.save | app.record.create.submit |
イベント名の一覧は、kintone 公式ドキュメント で確認できます。PC 用とモバイル用のイベントが別々に定義されていることにも注意してください。
REST API のエラーレスポンス
REST API のエラーは、レスポンスの message と code で原因を特定できます。
| エラーコード | メッセージ例 | 原因 |
|---|---|---|
GAIA_AP01 | 指定したアプリが見つかりません | アプリ ID が間違っている、またはアクセス権がない |
GAIA_RE01 | 指定したレコードが見つかりません | レコード ID が間違っている、レコードが削除されている |
GAIA_QU01 | クエリ形式が不正です | query パラメータの構文エラー |
GAIA_IL23 | 作成できるカーソルの上限に達しています | カーソルを閉じ忘れている |
GAIA_TM01 | リクエストの数が上限を超えています | 短時間に大量のリクエストを実行した |
CB_VA01 | 入力内容が正しくありません | 必須フィールドが未入力、値の形式が不正 |
(() => {
'use strict';
/**
* REST API のエラーをわかりやすく表示する
* @param { any } error - エラーオブジェクト
*/
const handleApiError = (error) => {
if (error && typeof error === 'object') {
// kintone.api のエラーレスポンス
const { message, code, id } = error;
console.error(`[${code}] ${message} (ID: ${id})`);
} else {
console.error('不明なエラー:', error);
}
};
kintone.events.on(['app.record.detail.show'], async (event) => {
try {
const response = await kintone.api(
kintone.api.url('/k/v1/records.json', true),
'GET',
{ app: 999999 } // 存在しないアプリ
);
console.log(response);
} catch (error) {
handleApiError(error);
// Console: [GAIA_AP01] 指定したアプリ(ID: 999999)が見つかりません。...
}
return event;
});
})();
実践的なデバッグテクニック
event オブジェクトの全体像を把握する
新しいイベントを使い始める際は、まず event オブジェクトの中身を確認しましょう。
(() => {
'use strict';
kintone.events.on(['app.record.detail.show'], (event) => {
// JSON.stringify で見やすく整形して出力
console.log(JSON.stringify(event, null, 2));
// どんなプロパティがあるかキー一覧で確認
console.log('event のキー:', Object.keys(event));
// record 内のフィールドコード一覧を確認
console.log('フィールドコード一覧:', Object.keys(event.record));
return event;
});
})();
カスタマイズの読み込み順序を確認する
kintone では、複数の JavaScript ファイルを登録できますが、上から順に読み込まれ、実行されます。ファイル間に依存関係がある場合は、読み込み順序が重要です。
// ファイル1: shared.js
console.log('shared.js が読み込まれました');
window.myApp = window.myApp || {};
window.myApp.config = { appId: 123 };
// ファイル2: main.js
console.log('main.js が読み込まれました');
console.log('config:', window.myApp?.config);
// shared.js が main.js より上に登録されていれば、config の値が取得できる
JavaScript ファイルの読み込み順序を変更した場合は、必ずブラウザのキャッシュをクリアしてからテストしてください。`Ctrl
- Shift + R
(Mac:Cmd + Shift + R`)でキャッシュを無視してリロードできます。
キャッシュのクリア
kintone の JavaScript / CSS カスタマイズは、ブラウザにキャッシュされることがあります。コードを更新したのに反映されない場合は、以下を試してください。
- ハードリロード:
Ctrl + Shift + R(Mac:Cmd + Shift + R) - キャッシュの無効化: DevTools → Network タブ → Disable cache にチェック(DevTools を開いている間のみ有効)
- シークレットウィンドウ: キャッシュの影響を排除して確認する
デバッグ時の注意点
本番環境でのデバッグ
本番環境で debugger ステートメントや大量の console.log を残さないように注意してください。開発中のデバッグコードは、本番にアップロードする前に必ず削除しましょう。
(() => {
'use strict';
// デバッグフラグ: 開発時は true、本番では false にする
const DEBUG = false;
const log = (...args) => {
if (DEBUG) {
console.log('[DEBUG]', ...args);
}
};
kintone.events.on(['app.record.detail.show'], (event) => {
log('イベント発火:', event.type);
log('レコード:', event.record);
// 本番でもログを出したい場合は console.error を使う
// console.error は意図的に残すログとして区別しやすい
return event;
});
})();
バンドラー(Webpack や Vite)を使っている場合は、ビルド時に console.log
を自動的に除去するプラグインを導入すると、うっかり本番に残してしまうリスクを減らせます。
まとめ
- Chrome DevTools の Console タブで
console.log、console.tableを使い分けて変数の値を確認する - Sources タブのブレークポイントや
debuggerステートメントを使えば、処理を一時停止して変数の状態をリアルタイムで確認できる - REST API のデバッグは Network タブで
k/v1でフィルタしてリクエスト・レスポンスを確認する TypeError: Cannot read properties of undefinedの多くは、フィールドコードの誤りが原因- イベントが発火しない場合は、イベント名のスペルミス、
return eventの有無、ファイルの登録順序を確認する - 本番環境には
debuggerや不要なconsole.logを残さないよう、デバッグフラグやバンドラーの設定で管理する