진단에 나온 코드를 찾아 다음에 살펴볼 곳을 확인할 수 있습니다. 예외 처리기를 쓸지 정하기 전에 발생 단계를 확인합니다.
코드부터 찾기
다음 전체 식은 실행 중 오류를 냅니다.
(car 1)코드와 메시지
E310 · car: expected a pair, got 1아래 E310 행을 보면 car에 넘긴 인자를 확인해야 한다는 것을 알 수 있습니다. (car '(1 2))처럼 쌍을 넘기면 결과는 1입니다. 전체 파일과 명령, 진단 위치를 읽는 법은 진단 매뉴얼에서 설명합니다.
실행 전 소스 오류 고치기
이 단계에서는 아직 처리기가 실행되지 않습니다. 소스를 고친 뒤 다시 실행합니다.
| 코드 | 단계 | 살펴볼 곳 |
|---|---|---|
| E100 | 리더 | 잘못된 토큰이나 맞지 않는 구분자. (+ 1 2처럼 닫는 )가 빠졌는지 확인합니다. |
| E110 | 정규화 | if 같은 예약어를 바인딩 이름으로 썼는지 확인하고 다른 이름을 고릅니다. |
| E120 | 리더 또는 정규화 | #;, define-syntax처럼 허용하지 않는 확장 문법이나 형식. |
| E130 | 정규화 | 형식에 필요한 구성 요소. 예를 들어 if에는 식 세 개가 필요합니다. |
| E140 | 리더 | 점 있는 리스트의 구조. 점의 위치와 뒤따르는 값을 확인합니다. |
| E150 | 리더 | 잘못된 문자열 이스케이프나 문자 리터럴. |
| E314 | 리더 | 1e999처럼 유한하지 않은 근사 수 리터럴. |
리더는 소스의 글자를 읽어 값과 형식으로 만듭니다. 정규화는 형식의 구조를 확인하고 축약 문법을 핵심 형식으로 바꿉니다.
실행 중 오류 고치거나 잡기
아래 오류는 실행이 문제가 있는 연산에 도달했을 때 발생합니다. guard로 잡으면 선택된 절이 guard 식의 결과를 반환합니다.
| 코드 | 원인 | 살펴볼 곳 |
|---|---|---|
| E300 | 정의되지 않은 이름을 읽음 | 진단 위치의 이름과 그 이름을 정의한 곳. |
| E301 | 프로시저가 아닌 값을 호출함 | 호출에서 프로시저 자리에 놓인 값. |
| E302 | 인자 수가 맞지 않음 | 프로시저의 매개변수와 전달한 인자 수. |
| E303 | 바인딩되지 않은 이름에 set!을 사용함 | 대입하기 전에 이름을 바인딩했는지 확인합니다. |
| E310 | 연산에 필요한 쌍이나 리스트가 아님 | car, cdr 또는 진단에 나온 리스트 프로시저에 넘긴 인자. |
| E311 | 인덱스가 범위를 벗어남 | 인덱스와 접근하려는 값의 크기. |
| E312 | 내장 프로시저에 잘못된 타입을 넘김 | 해당 프로시저가 받는 타입. |
| E313 | 0으로 나눔 | 나누는 수. |
| E314 | 근사 수 계산의 결과가 유한하지 않음 | 산술 연산과 피연산자의 크기. |
| E320 | 해당 자리가 받는 값 개수와 반환한 값 개수가 다름 | 받는 식이 값 하나를 요구하는지, 여러 값을 받는지 확인합니다. |
| E321 | letrec 바인딩을 초기화하기 전에 읽음 | 초깃값을 계산하는 동안 참조하는 이름. |
| E340 | 탈출 연속을 더는 사용할 수 없음 | 이미 사용했거나 해당 연속을 만든 호출이 끝났는지 확인합니다. |
읽기 단계의 E314는 잡을 수 없습니다. 실행 중 산술 연산에서 발생한 E314는 잡을 수 있습니다.
탈출 연속은 call/cc가 자신의 호출을 일찍 끝내도록 만드는 프로시저입니다. 그 호출이 끝나기 전에 한 번만 사용할 수 있습니다.
발생시킨 객체와 처리기 오류 다루기
| 코드 | 원인 | 처리 방법 |
|---|---|---|
| E330 | (error message …)가 오류 객체를 발생시킴 | guard가 객체를 받습니다. 메시지와 오류에 덧붙인 값을 확인합니다. |
| E331 | 발생시킨 객체가 처리되지 않은 채 최상위까지 전달됨 | guard나 처리기로 잡습니다. raise는 어떤 값이든 전달하므로 오류 객체의 필드를 읽기 전에 error-object?로 확인합니다. |
| E332 | 재개할 수 없는 오류를 받은 처리기가 정상 반환함 | 바깥 처리기가 이 새 오류를 잡을 수 있습니다. 실패한 식을 벗어나려면 guard를 씁니다. 처리기의 반환값으로 실행을 이어가려면 raise-continuable을 씁니다. |
맞는 guard 절이 없고 else도 없으면 원래 발생시킨 객체를 다시 발생시킵니다. raise-continuable은 처리기의 결과를 오류가 발생한 호출로 돌려줍니다. 두 처리 방식의 예제는 오류 가이드에 있습니다.
폐기 예정 이름 바꾸기
경고는 발생 순서를 유지합니다. 해당 폐기 예정 프로시저를 실제로 호출하면 소스의 호출 위치마다 한 번만 경고합니다. 연산이 뒤이어 실패해도 경고는 남습니다. 같은 이름을 다른 값에 연결한 바인딩에서는 해당 별칭 경고가 나오지 않습니다.
| 코드 | 경고가 나오는 호출 | 새 코드에 쓸 이름 |
|---|---|---|
| W330 | % | modulo |
| W331 | list-first 또는 list-rest | 각각 first 또는 rest |
자원 한도에 대응하기
ResourceLimit은 잡을 수 있는 E3xx 오류와 별도의 자원 결과를 나타냅니다. 비꼬리 호출은 호출한 프로시저가 반환한 뒤에도 할 일이 남은 호출입니다. 이런 호출의 깊이가 한도에 도달하면 네이티브 명령은 recursion-limit을 보고합니다. 종료 상태는 2입니다.
작업량을 줄이거나 선언한 자원 프로파일을 검토합니다. 자원 한도로 멈춘 실행은 예외 처리기로 이어갈 수 없습니다.