본문 바로가기
프로그래밍/자바

Stack Trace 바로 확인할 수 있는 개발용 에러 페이지 만들기

by pentode 2018. 4. 17.

자바로 웹 개발시 에러가 발생하면 서버나 브라우저의 에러 페이지가 아니라 커스텀 에러페이지를 보여주도록 설정을 합니다. 이 설정은 web.xml 파일에서 아래와 같이 해 줄 수 있습니다.

 

<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/views/error.jsp</location>
</error-page>

 

보안 때문에 모든 에러에 동일한 에러페이지를 설정하기도 하고, 에러코드 별로 다른 에러페이지를 설정하기도 합니다.


실제 에러페이지의 내용은 보안 목적상 에러 내용을 통해서 서버 정보를 취득하지 못하도록 간단한 에러발생 알림만 보여주게 만듭니다. 디버깅에 필요한 정보들은 로그파일에 남기게 됩니다. 물론 로그 파일에도 디버깅을 위한 최소한의 정보만 남기고, 개인정보 등 민감한 정보가 남지 않도록 주의해야 합니다.


이번에 볼 내용은 개발용으로만 사용되어야 할 것으로, 에러 페이지 내에서 떡하니 스택트레이스까지 출력하는 방법입니다. 개발용 콘솔의 로그를 확인해도 되지만 쏟아지는 로그속에서 보물을 찾기가 쉽지만은 않습니다. 일단 화면에서 빠르게 예외를 확인하고, 필요하면 로그를 뒤지던가 하면 되겠습니다.



error.jsp 파일 내용입니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<%@ page import="java.io.PrintWriter"%>
<%@ page import="java.io.ByteArrayOutputStream"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>에러 발생</title>
</head>

<h3>요청 처리 과정에서 에러가 발생하였습니다.</h3>
<pre>
에러 타입 : <%= exception.getClass().getName() %>
에러 메세지 : <%= exception.getMessage() %>
스택 트레이스 :
<%
ByteArrayOutputStream baos = null;
PrintWriter pw = null;

try {
	baos = new ByteArrayOutputStream();
	pw = new PrintWriter(baos);

	exception.printStackTrace(pw);
	
	pw.flush();
	
	out.print(baos.toString());
	
} catch(Exception e) {
	e.printStackTrace();
} finally {
	if(pw != null) try { pw.close(); } catch(Exception igonre) {}
	if(baos != null) try { baos.close(); } catch(Exception ignore) {}
}
%> 
</pre>
</body>
</html>

 

이 페이지가 에러 페이지임을 나타내는 구문입니다. 이 구문을 사용함으로써 exception 내장 객체를 사용할 수 있게 됩니다.


<%@ page isErrorPage="true" %>


스택 트레이스를 출력하기 위해서 예외 객체가 가지는 스택트레이스를 출력하는 메소드중에 다른 출력 스트림으로 내용을 보낼 수 있는 메소드를 사용합니다.


printStackTrace(PrintWriter pw)


스택트레이스 내용을 문자열로 만들기 위해서 메모리에 스트림으로 데이터를 쓸 수 있는 ByteArrayOutputStream 을 사용합니다.


이제 이것들을 조합해서 스택트레이스 내용을 문자열로 만들어서 페이지에 출력합니다. 예외 처리 없이 간단히 적어보면 다음과 같습니다.

 

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);

exception.printStackTrace(pw);
pw.flush();
String stackTrace = baos.toString();

 

출력전에 반드시 PrintWriter을 flush() 해줘야 됩니다. 그래야만 버퍼의 내용이 모두 메모리에 쓰여지게 됩니다.


에러내용이 출력된 결과 입니다.





이렇게 에러가 바로 출력되는 에러페이지가 운영에 배포되면 절대 안되겠습니다.


※ 추가


간단하게 다음 처럼 사용할 수 도 있습니다.


<% exception.printStackTrace(new java.io.PrintWriter(out)); %>

반응형