5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【kintone】カスタマイズで発生したエラーをアプリに保存する

Last updated at Posted at 2025-02-05

kintoneのカスタマイズのエラーについて

kintoneのカスタマイズはブラウザのJavaScriptを記述することになります。なので、エラーは各々のユーザーのブラウザ上で起こり、サーバーではないので、エラーを捕まえて分析するのがとても難しいです。

今回はkintoneにエラーをためるアプリを作り、そこにエラー内容を登録してしまう方法について考えてみます。

作るもの

  • エラーをためるkintoneアプリ
  • 実際に運用されるkintoneアプリ
  • カスタマイズ内容であるJavaScriptファイル

qiita01.gif

実際に運用されるkintoneアプリはなんでもいいです。今回はEOL材料管理にしてみました。特に意味はありません😌

実装

それでは作ってみましょう。

エラーをためるkintoneアプリ

image.png

上記のような内容でアプリを作ります。項目は以下のようにしてみました。

  • アプリID
    • エラーを起こしたアプリのアプリID
  • URL
    • エラーが起きた画面のURL
  • スタックトレース
    • エラーの内容
  • ユーザー
    • エラーに遭遇したユーザー

URLは、アプリIDを取得してもどの画面で起きたか分からないので、取得します。ただし、統計情報などを取得するときにアプリIDは欲しいので、別の項目にしています。

ユーザーを保存する理由は、エラーを貯めるアプリは管理者権限にするので、一般ユーザーからは見えません。なので、APITokenを利用したアクセスにより、データを作成することになります。

APITokenを利用したデータ作成では、作成者がAdministratorになってしまい、実際にエラーに遭遇したユーザーが分からなくなってしまいます。

そのため、ユーザーを別項目にしています。

カスタマイズ

エラーを登録する関数は以下のようになります。

/**
 * エラーを登録する
 * @param {Error} e 
 */
async function persistError(e) {

    //kintoneアプリにエラーを登録する。
    const client = new KintoneRestAPIClient({
        auth: {
            apiToken: ERROR_TRACE_APP_TOKEN
        }
    });

    await client.record.addRecord({
        app: ERROR_TRACE_APP,
        record: {
            "ユーザー": {
                //APITokenを使っているので、ログインユーザーがわからないので、ログインユーザー情報を保存
                value: [kintone.getLoginUser()]
            },
            "アプリID": {
                //どこのアプリか
                value: kintone.app.getId(),
            },
            "スタックトレース": {
                //スタックトレースを保存
                value: e.stack
            },
            "URL": {
                //どの画面で発生したか
                value: location.href
            },
        }
    });
}


エラーオブジェクトの.stackにスタックトレースが格納されています。

アクセスはKintoneRestAPIClientを利用します。このライブラリでは、authプロパティに接続方式を記述します。今回はAPITokenを利用するので、apiTokenをセットしています。

//kintoneアプリにエラーを登録するためのボタンを作成
const $$button = document.createElement('button');
$$button.id = `error-trace-button`;
$$button.textContent = 'Hello Error';
$$button.addEventListener('click', async () => {
    try {
        alert('このダイアログを閉じるとエラーが発生します。');

        //エラーを発生させる。
        throw new Error('Hello Error');

    } catch (e) {
        console.warn(e);
        await persistError(e);
    }
});


kintone.events.on(
    ['app.record.index.show'],
    async (ev) => {
        //一覧画面の、ヘッダーに追加します。
        const $$el = kintone.app.getHeaderMenuSpaceElement();
        if (!$$el.contains($$button)) {
            $$el.appendChild($$button);
        }
        return ev;
    }
)

エラーを起こすコードはこんな感じです。
ボタンを押すと、エラーをthrowする感じですね。

コード全文


(() => {
    'use strict';

    // エラーを記録するアプリのID
    const ERROR_TRACE_APP = `291`; 
    // エラーを記録するアプリのトークン
    const ERROR_TRACE_APP_TOKEN = `JAfuTfxDH0uuuuuuuuuuuuuuuuuuuw`; 

    //kintoneアプリにエラーを登録するためのボタンを作成
    const $$button = document.createElement('button');
    $$button.id = `error-trace-button`;
    $$button.textContent = 'Hello Error';
    $$button.addEventListener('click', async () => {
        try {
            alert('このダイアログを閉じるとエラーが発生します。');

            //エラーを発生させる。
            throw new Error('Hello Error');

        } catch (e) {
            console.warn(e);
            await persistError(e);
        }
    });


    kintone.events.on(
        ['app.record.index.show'],
        async (ev) => {
            const $$el = kintone.app.getHeaderMenuSpaceElement();
            if (!$$el.contains($$button)) {
                $$el.appendChild($$button);
            }
            return ev;
        }
    )

    /**
     * エラーを登録する
     * @param {Error} e 
     */
    async function persistError(e) {

        //kintoneアプリにエラーを登録する。
        const client = new KintoneRestAPIClient({
            auth: {
                apiToken: ERROR_TRACE_APP_TOKEN
            }
        });

        await client.record.addRecord({
            app: ERROR_TRACE_APP,
            record: {
                "ユーザー": {
                    //APITokenを使っているので、ログインユーザーがわからないので、ログインユーザー情報を保存
                    value: [kintone.getLoginUser()]
                },
                "アプリID": {
                    //どこのアプリか
                    value: kintone.app.getId(),
                },
                "スタックトレース": {
                    //スタックトレースを保存
                    value: e.stack
                },
                "URL": {
                    //どの画面で発生したか
                    value: location.href
                },
            }
        });
    }
})();

まとめ

  • Error.stackにスタックトレースが格納されている
  • kintoneにエラー内容を保存することができる
  • KintoneRestAPIの認証形式をApiTokenにしてくことで、権限を気にせずレコードを追加できる

すべての場面でエラーをアプリに登録することが有効というわけではありませんが、原因不明なガンコな不具合に、利用されてもよいのではないかと思っています。

注意)アプリのAPIトークンについては、セキュリティ上の問題から、ハードコードしないほうがいいです。今回は分かりやすさのために、コードを掲載しています。


この記事は以上です。ありがとうございました。

kintoneのプラグイン開発や研修などを行っています。
お仕事のお話はこちらまで。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?