게시판에 첨부파일을 올리는 기능을 맡았다. 화면에는 저장됐다고 나오는데 서버에 파일이 없었다.
Table of contents
Open Table of contents
오류가 안 났다
FileOutputStream으로 쓰는 코드였는데 예외가 안 잡혔다. try 블록을 지나 정상 응답까지 갔다.
Tomcat 로그에도 아무것도 없었다. 어디를 봐야 할지 몰라 한참 헤맸다.
빈 catch 블록
catch (Exception e) 안이 비어 있었다. 앞사람이 넣어 둔 것인데 그 안에서 아무것도 안 하고 있었다.
e.printStackTrace()를 넣고 다시 올려 보니 FileNotFoundException이 찍혔다.
java.io.FileNotFoundException: /home/upload/2011/08/a.jpg (No such file or directory)
파일이 없다는 게 아니라 쓸 자리가 없다는 뜻이었다. /home/upload/2011/08 폴더가 없었다.
폴더는 저절로 안 생긴다
FileOutputStream은 파일을 만들지만 상위 폴더는 만들지 않는다. 연·월로 폴더를 나누게 해 뒀는데 8월이 되면서 2011/08이 새로 필요해진 것이었다.
7월까지는 됐다. 그 폴더는 처음 만들 때 손으로 만들어 뒀기 때문이다.
File.mkdirs()를 쓰면 중간 폴더까지 만든다는 것을 API 문서에서 봤다. mkdir()은 한 단계만 만들어서 2011 폴더가 없으면 2011/08이 실패한다.
뜰 때 확인하게 했다
쓰기 직전에 mkdirs()를 부르게 했다. mkdirs()는 예외를 던지지 않고 boolean을 돌려주므로 그 값을 확인해 실패하면 로그를 남긴다. 그리고 ServletContextListener에서 애플리케이션이 뜰 때 업로드 최상위 폴더가 있는지, 쓰기 권한이 있는지 확인하게 했다.
없으면 로그에 남기고 뜨는 것은 막지 않았다. 업로드 말고 다른 기능은 돌아야 하기 때문이다.
빈 catch도 전부 찾아 로그를 남기게 했다. 프로젝트에 여섯 군데 있었다.
정리
- 빈
catch는 오류를 없애는 것이 아니라 안 보이게 만든다 FileNotFoundException은 쓸 자리가 없을 때도 난다FileOutputStream은 상위 폴더를 만들지 않는다mkdirs()는 중간 폴더까지,mkdir()은 한 단계만 만든다- 연·월로 폴더를 나누면 달이 바뀔 때 없는 폴더가 생긴다
- 쓰기 직전에
mkdirs()를 부르고 뜰 때 최상위 폴더를 확인한다 - 확인은 로그만 남기고 기동은 막지 않았다