진단을 읽으면 코드에서 고칠 위치를 찾을 수 있습니다. 실행 중 발생한 오류는 guard로 잡아 프로그램이 반환할 결과를 정합니다.
아래 파일 예제는 첫 프로그램에서 설치한 네이티브 lispex 명령을 사용합니다.
E100이 나면 소스부터 고치기
다음 전체 코드를 syntax.lspx로 저장합니다. 닫는 괄호가 빠져 있습니다.
(+ 1 2파일을 실행합니다.
lispex run syntax.lspx명령은 표준 오류에 다음 진단을 쓰고 종료 상태 1로 끝납니다. 표준 출력은 비어 있습니다.
E100 syntax.lspx:1:1 unterminated list (missing `)`)syntax.lspx:1:1은 닫히지 않은 리스트가 시작하는 1행 1열을 가리킵니다. 닫는 괄호를 추가합니다.
(+ 1 2)같은 명령을 다시 실행합니다.
lispex run syntax.lspx3이제 명령은 표준 출력에 3을 쓰고 종료 상태 0으로 끝납니다. 두 실행 모두 결과 파일을 만들지 않습니다.
E100은 리스펙스가 소스를 읽는 동안 발생합니다. 아직 guard가 실행되기 전이므로 소스를 먼저 고칩니다.
실행 중 발생한 오류 처리하기
다음 전체 코드를 user-error.lspx로 저장합니다.
(guard (e ((error-object? e) (error-object-message e))) (error "bad input"))lispex run user-error.lspx"bad input"명령은 종료 상태 0으로 끝납니다. 표준 오류는 비어 있고 결과 파일은 생기지 않습니다.
error가 메시지"bad input"을 담은 오류 객체를 만듭니다.guard가 그 객체를 잡아e에 연결합니다.error-object?가 값을 확인합니다. 조건에 맞는 절이 메시지를 반환합니다.
guard 식 전체가 문자열을 반환합니다. 실패한 error 호출부터 실행을 이어가지는 않습니다. 오류 객체는 error-object?, error-object-message, error-object-irritants로 살펴봅니다. 화면에 표시된 진단 문자열을 분석해서 처리하지 않습니다.
소스를 고칠지 오류를 처리할지 정하기
| 상황 | 할 일 |
|---|---|
| 실행 전에 소스를 읽거나 형식을 확인하다가 실패함 | 표시된 소스를 고칩니다. 아직 처리기가 실행되기 전입니다. |
| 잡을 수 있는 실행 중 오류가 발생함 | 연산을 고치거나 guard로 적절한 결과를 반환합니다. |
맞는 guard 절이 없고 else도 없음 | 원래 발생시킨 객체를 다시 발생시켜 바깥 처리기로 전달합니다. |
| 자원 한도에 도달함 | 작업량을 줄이거나 자원 프로파일을 검토합니다. guard로 ResourceLimit을 잡을 수는 없습니다. |
| 호출 애플리케이션이 비정상 종료함 | 애플리케이션의 실패 원인을 조사합니다. 리스펙스 오류 객체로 바뀌지 않습니다. |
오류를 발생시킨 자리에서 계속 실행하기
처리기 프로시저가 필요하면 with-exception-handler를 씁니다. raise-continuable을 쓰면 처리기가 반환한 값을 오류가 발생한 호출에서 받아 실행을 계속합니다.
다음 전체 예제를 플레이그라운드에 입력합니다.
(with-exception-handler
(lambda (e) 10)
(lambda () (+ 1 (raise-continuable "retry"))))결과
11처리기가 10을 반환하면 +가 1을 더합니다. 대신 raise를 쓰면 처리기가 정상 반환할 때 E332가 발생합니다. 실패한 식을 벗어나 바깥의 guard에서 결과를 반환하려면 guard를 씁니다.