오류 처리
오류 처리 (Error Handling)
루아는 몇 가지 운영체제 요인 — 예를 들어 메모리 부족, 산술 오버플로(arithmetic overflow), 스택 넘침(stack overflow) — 외에 대부분의 오류를 포착(catch)할 수 있어요. 루아 코드가 오류를 만나면 보호된 호출(protected call)로 오류를 잡을 수 있어요. pcall(또는 xpcall) 함수는 주어진 함수를 보호 모드(protected mode)로 호출해요.
pcall로 함수를 호출하면, 함수가 성공하면 true와 그 반환값을 돌려주고, 오류가 발생하면 false와 오류 메시지를 돌려줘요. 이를 통해 프로그램은 실행을 멈추지 않고 오류를 처리할 수 있어요.
local ok, err = pcall(function()
-- 위험한 코드
end)
if not ok then
print("오류 발생:", err)
end
오류 메시지는 문자열이 아니라 어떤 값이든 될 수 있어요. 루아는 오류를 "던질(throw)" 때 그 값을 값 그대로 오류 메시지로 사용해요. error 함수를 호출하면 명시적으로 오류를 발생시키는데, error(message [, level]) 형태예요.
level이 1이면 오류 위치를error를 호출한 위치로,- 2이면
error를 호출한 함수를 호출한 위치로, - 0이면 오류 위치 정보를 추가하지 않아요.
후처리 후 실행(After-error) — 루아는 오류가 처리된 뒤에도 언어 수준에서 "후처리 모드(finalizers)"를 지원해요. toclose로 표시하거나 __close 메타메서드를 가진 변수는 블록을 벗어날 때 자동으로 정리돼요 (to-be-closed 변수 참조).
오류 메시지의 위치 정보 — 루아는 실행 시 오류가 나면 오류 메시지에 소스 파일 이름과 줄 번호를 덧붙이는 경우가 많아요. 예를 들어 lua: test.lua:3: attempt to perform arithmetic on a nil value 같은 형태가 돼요. 이 위치 정보는 C API에서도 lua_error나 luaL_error 같은 함수로 오류를 만들 때 활용돼요.
본문
오류 포착 (Catching Errors)
pcall(f, ...)는 f를 보호 모드로 호출하고, 성공 시 true와 결과값을, 실패 시 false와 오류 객체를 반환해요. 오류가 발생하면 f의 실행 스택은 풀리고, pcall 지점으로 제어가 돌아와요. 실패한 호출이 오류를 일으킨 책임이 어디 있는지, 그리고 남은 스택이 어떻게 처리되는지는 pcall의 세부 동작에 의해 결정돼요.
오류 객체 (Error objects)
오류 객체를 만들 때 루아는 "오류 객체 생성 위치"를 태그로 기록하지 않아요. 다만 error의 level 인자를 통해 위치를 붙일 수 있어요. xpcall(f, msgh, ...)는 오류가 발생했을 때 msgh라는 메시지 핸들러를 호출해 오류를 더 풍부하게 만들 수 있게 해줘요.
보호되지 않은 호출 (Unprotected calls)
pcall 없이 루아 코드가 오류를 만나면, 루아는 보통 "unprotected error in call to..." 라는 오류를 냅니다. 가장 바깥쪽의 보호되지 않은 호출(예: 독립 실행 인터프리터의 최상위 실행)에서 오류가 나면, 루아는 오류 메시지를 화면에 출력하고 실행을 중단해요.