안녕하세요,
지금 이직 사이에 있어서 100줄짜리 프로그램에 헷갈릴 시간은 넘치게 많아요.
ledger-import는 세미콜론 CSV를 읽어서 정리된 행을 staging 파일에 써요. 파일 전체가 파싱되지 않으면 staging에 아무것도 남아 있으면 안 돼요. 테스트 파일 data/march.csv는 4번째 줄에 금액이 깨져 있어요 (-12,5x). 저는 import rejected: line 4: bad amount ...가 나오고 exit code 2가 될 거라고 생각했어요. 그런데 실제로는 아래처럼 나오고 exit code는 3이에요:
SEVERE: staging problem: staging file build/staging.tmp closed with 2 uncommitted rows
줄 번호도, 잘못된 값도 어디에도 안 나와요. parse()의 catch 블록에 임시로 System.err.println을 넣으면 출력은 되니까 ImportFailure는 분명히 만들어지고 있어요. 다만 Main까지 도착하지 않을 뿐이에요. 4번째 줄을 고치면 import는 잘 돼요.
처음엔 Main의 catch 순서와 logging.properties 설정을 의심했어요. 두 catch 블록의 순서를 바꿔 봤지만 쓸 만한 변화는 없었어요. 관련 부분은 이래요:
// Importer.run()
StagingWriter writer = new StagingWriter(staging);
try {
...
writer.add(parse(lineNo, line));
...
writer.commit();
return writer.count();
} finally {
writer.close();
}
// StagingWriter.close()
out.close();
if (!committed && rows > 0) {
Files.deleteIfExists(path);
throw new IOException("staging file " + path + " closed with " + rows + " uncommitted rows");
}
Main은 ImportFailure를 먼저 catch하고(exit 2), 그다음 IOException을 catch해요(exit 3).
혹시 로깅은 아예 문제가 아닐 가능성이 있을까요? 제 예외는 어디로 가는 건가요?
영어에서 번역·원문 보기Hello,
I am between jobs, so I have all the time in the world to be confused by a 100-line program.
ledger-import reads a semicolon CSV and writes cleaned rows to a staging file. Nothing is allowed to stay in staging unless the whole file parses. My test file data/march.csv has a broken amount on line 4 (-12,5x). I expected import rejected: line 4: bad amount ... and exit code 2. What I get is this, with exit code 3:
SEVERE: staging problem: staging file build/staging.tmp closed with 2 uncommitted rows
The line number and the bad value appear nowhere. With a temporary System.err.println in the catch block of parse(), it does print, so the ImportFailure really is created. It just never arrives in Main. When I fix line 4 the import works fine.
My first suspects were the catch order in Main and the logging.properties setup. Swapping the two catch blocks changed nothing useful. The relevant parts:
// Importer.run()
StagingWriter writer = new StagingWriter(staging);
try {
...
writer.add(parse(lineNo, line));
...
writer.commit();
return writer.count();
} finally {
writer.close();
}
// StagingWriter.close()
out.close();
if (!committed && rows > 0) {
Files.deleteIfExists(path);
throw new IOException("staging file " + path + " closed with " + rows + " uncommitted rows");
}
Main catches ImportFailure first (exit 2), then IOException (exit 3).
Is there a possibility that the logging is not the problem at all? Where does my exception go?