오류를 읽고 처리하기

진단에서 고칠 위치를 찾고, 실행 중 발생한 오류는 guard로 처리합니다.

진단을 읽으면 코드에서 고칠 위치를 찾을 수 있습니다. 실행 중 발생한 오류는 guard로 잡아 프로그램이 반환할 결과를 정합니다.

아래 파일 예제는 첫 프로그램에서 설치한 네이티브 lispex 명령을 사용합니다.

E100이 나면 소스부터 고치기

다음 전체 코드를 syntax.lspx로 저장합니다. 닫는 괄호가 빠져 있습니다.

LISPEX
(+ 1 2

파일을 실행합니다.

BASH
lispex run syntax.lspx

명령은 표준 오류에 다음 진단을 쓰고 종료 상태 1로 끝납니다. 표준 출력은 비어 있습니다.

E100 syntax.lspx:1:1 unterminated list (missing `)`)

syntax.lspx:1:1은 닫히지 않은 리스트가 시작하는 1행 1열을 가리킵니다. 닫는 괄호를 추가합니다.

LISPEX
(+ 1 2)

같은 명령을 다시 실행합니다.

BASH
lispex run syntax.lspx
3

이제 명령은 표준 출력에 3을 쓰고 종료 상태 0으로 끝납니다. 두 실행 모두 결과 파일을 만들지 않습니다.

E100은 리스펙스가 소스를 읽는 동안 발생합니다. 아직 guard가 실행되기 전이므로 소스를 먼저 고칩니다.

실행 중 발생한 오류 처리하기

다음 전체 코드를 user-error.lspx로 저장합니다.

LISPEX
(guard (e ((error-object? e) (error-object-message e))) (error "bad input"))
BASH
lispex run user-error.lspx
"bad input"

명령은 종료 상태 0으로 끝납니다. 표준 오류는 비어 있고 결과 파일은 생기지 않습니다.

  1. error가 메시지 "bad input"을 담은 오류 객체를 만듭니다.
  2. guard가 그 객체를 잡아 e에 연결합니다.
  3. error-object?가 값을 확인합니다. 조건에 맞는 절이 메시지를 반환합니다.

guard 식 전체가 문자열을 반환합니다. 실패한 error 호출부터 실행을 이어가지는 않습니다. 오류 객체는 error-object?, error-object-message, error-object-irritants로 살펴봅니다. 화면에 표시된 진단 문자열을 분석해서 처리하지 않습니다.

소스를 고칠지 오류를 처리할지 정하기

상황할 일
실행 전에 소스를 읽거나 형식을 확인하다가 실패함표시된 소스를 고칩니다. 아직 처리기가 실행되기 전입니다.
잡을 수 있는 실행 중 오류가 발생함연산을 고치거나 guard로 적절한 결과를 반환합니다.
맞는 guard 절이 없고 else도 없음원래 발생시킨 객체를 다시 발생시켜 바깥 처리기로 전달합니다.
자원 한도에 도달함작업량을 줄이거나 자원 프로파일을 검토합니다. guard로 ResourceLimit을 잡을 수는 없습니다.
호출 애플리케이션이 비정상 종료함애플리케이션의 실패 원인을 조사합니다. 리스펙스 오류 객체로 바뀌지 않습니다.

오류를 발생시킨 자리에서 계속 실행하기

처리기 프로시저가 필요하면 with-exception-handler를 씁니다. raise-continuable을 쓰면 처리기가 반환한 값을 오류가 발생한 호출에서 받아 실행을 계속합니다.

다음 전체 예제를 플레이그라운드에 입력합니다.

LISPEX
(with-exception-handler
  (lambda (e) 10)
  (lambda () (+ 1 (raise-continuable "retry"))))

결과

출력
11

처리기가 10을 반환하면 +가 1을 더합니다. 대신 raise를 쓰면 처리기가 정상 반환할 때 E332가 발생합니다. 실패한 식을 벗어나 바깥의 guard에서 결과를 반환하려면 guard를 씁니다.

진단의 발생 단계 읽기 · 오류 코드 찾기 · 결정 기록