現場で、フロントエンド側(JavaScript)で発生したエラーを、
servlet側に渡して、ログに出力したいという要件が有りました。
あまり求められたことが無い、珍しい要件だったので、
その時とったアプローチ方法をメモしておこうと思います。
対応方法
大まかに以下のような形で対応を行いました。
①JavaScriptでエラーが発生→window.onerror(JavaScript)でエラーをキャッチ
②キャッチしたエラー情報を、servlet側に渡せるように、jsp上のhiddenタグに設定
③jspからservletに、エラー情報をポスト
④JavaScriptで発生したエラー情報を、servlet内で文字列の情報として利用
◯参考情報:MDN window.onerror
その時に、検証用に作成したプロジェクトのソースをメモしておこうと思います。
検証プロジェクト 内容
JavaScriptエラーを意図的に発生させるdoErrorボタンと、
発生したエラー内容をservlet側にpostするpostErrorボタンを用意しました。
doErrorボタンを実行すると、JavaScriptエラーが発生し、
エラー内容を、htmlに表示します。
エラーが表示されている状態で、postErrorボタンをクリックすると、
postされてservlet側にエラー内容が届きます。
検証用ファイル JavaScript
意図的にJavaScriptエラーを発生させるFunctionを作成しました。
また、windows.onerrorをエラーハンドリングとして利用しています。
// 意図的にJavaScriptエラーを発生させるFunction.
function doError(){
let aa = "";
aa - bb; // do error.
console.log("click test.");
}
// JavaScript内でエラーが発生した場合、呼び出されるFunction.
window.onerror = function (msg, file, line, column, err) {
// ブラウザコンソール出力
console.log("msg:" + msg)
console.log("err:" + err)
console.log("file:" + file)
console.log("line:" + line)
console.log("colum:" + column)
// エラー内容整形
let em = "msg:" + msg;
em += " </br> err:" + err;
em += " </br> file:" + file;
em += " </br> line:" + line + " colum:" + column;
// 画面上部に表示
document.getElementById("showErrorDiv").innerHTML = em;
// form内のhiddenに値設定
document.getElementById("showErrorInput").value = em;
};
検証用ファイル Jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JsError Practice01</title> <script src="/jsErrorPractice01/js/errorTest.js"></script> </head> <body> <div>JsError Practice01</div> <hr> <div id="showErrorDiv"></div> <input type="button" onclick="doError()" value="doError" /> <hr> <form action="./CatchJsError" method="post"> <input type="hidden" id="showErrorInput" name="showErrorInput" /> <input type="submit" value="postError" /> </form> </body> </html>
検証用ファイル Servlet
postされたエラー情報を抽出して、出力確認を行なっています。
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloWorld
*/
@WebServlet("/CatchJsError")
public class CatchJsError extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CatchJsError() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String view = "/index.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(view);
dispatcher.forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Postされた、JavaScriptエラーをhttpParamから抽出
String errorMsg = request.getParameter("showErrorInput");
// 画面表示用に改行置き換え
System.out.println(errorMsg.replace("</br>", System.getProperty("line.separator")));
// 画面更新処理
String view = "/index.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(view);
dispatcher.forward(request, response);
}
}
以上が、メモ内容となります。
余談ですが、JavaScriptのフレームワークを採用している場合、
window.onerrorでは、全てのエラーを拾うことが出来ない場合もあります。
フレームワークを採用している場合、フレームワークで実装されている
エラーハンドラを利用することをお勧めします。

