예외 처리 문법
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
- 1. 개요
 - 2. 주요 프로그래밍 언어의 예외 처리 문법
- 2.1. [[C++]]
 - 2.2. [[Java]]
 - 2.3. [[C#]]
 - 2.4. [[Python]]
 - 2.5. [[JavaScript]]
 - 2.6. [[PHP]]
 - 2.7. [[Ruby]]
 - 2.8. [[Swift]]
 - 2.9. 기타 언어
- 2.9.1. [[Ada]]
 - 2.9.2. [[Assembly language]]
 - 2.9.3. [[ATS]]
 - 2.9.4. [[Bash]]
 - 2.9.5. [[BASIC]]
 - 2.9.6. [[C]]
 - 2.9.7. [[ColdFusion Markup Language|CFML]]
 - 2.9.8. [[D]]
 - 2.9.9. [[Delphi]]
 - 2.9.10. [[Erlang]]
 - 2.9.11. [[F#]]
 - 2.9.12. [[Haskell]]
 - 2.9.13. [[Common Lisp]]
 - 2.9.14. [[Lua]]
 - 2.9.15. [[Next Generation Shell]]
 - 2.9.16. [[Objective-C]]
 - 2.9.17. [[OCaml]]
 - 2.9.18. [[Perl]]
 - 2.9.19. [[PowerBuilder]]
 - 2.9.20. [[PowerShell]]
 - 2.9.21. [[R]]
 - 2.9.22. [[Rebol]]
 - 2.9.23. [[Rexx]]
 - 2.9.24. [[S-Lang]]
 - 2.9.25. [[Smalltalk]]
 - 2.9.26. [[Tcl]]
 - 2.9.27. [[VBScript]]
 - 2.9.28. [[Visual Basic 6]]
 - 2.9.29. [[Visual Basic .NET]]
 - 2.9.30. [[Visual Prolog]]
 - 2.9.31. [[X++]]
 
 
 - 참조
 
1. 개요
예외 처리 문법은 프로그래밍 언어에서 프로그램 실행 중 발생할 수 있는 예외 상황을 처리하기 위한 구조이다. C++, Java, C#, Python, JavaScript, PHP, Ruby, Swift 등 다양한 언어에서 try, catch, finally, throw 등의 키워드를 사용하여 예외를 처리한다. 각 언어는 예외 처리 방식에 차이가 있으며, C++는 try-catch-throw 구조를 사용하고, Java는 try-catch-finally 구조를, Python은 try-except-finally 구조를, C#은 try-catch-finally 구조를 사용한다. 또한, 언어별로 특정 예외 클래스를 제공하거나, 사용자 정의 예외를 지원하기도 하며, 예외 발생 시 프로그램의 흐름을 제어하고 자원 관리를 수행하는 데 사용된다. 
다양한 프로그래밍 언어는 각기 다른 문법과 접근 방식을 통해 예외 처리 기능을 제공한다. 이는 언어의 설계 철학이나 주 사용 목적에 따라 달라진다.
2. 주요 프로그래밍 언어의 예외 처리 문법
많은 현대 언어들은 C++, Java, C#, Python 등과 같이 `try-catch` (또는 유사한 키워드: `try-except`, `try-rescue` 등) 블록을 사용하여 예외 발생 가능성이 있는 코드를 감싸고, 발생한 예외를 종류별로 처리하는 구조를 채택하고 있다. 일부 언어는 여기에 `finally` 또는 `ensure` 블록을 추가하여 예외 발생 여부와 관계없이 항상 실행되어야 하는 마무리 코드를 작성할 수 있도록 지원한다.
반면, C와 같이 언어 자체적으로 예외 처리 문법을 지원하지 않는 경우, 함수의 반환값을 확인하거나 특정 라이브러리 함수(`setjmp`/`longjmp`)를 사용하는 방식으로 오류를 처리해야 한다. 함수형 프로그래밍 언어 중 일부는 모나드와 같은 개념을 활용하여 오류 상황을 값으로 다루기도 한다.
아래에서는 주요 프로그래밍 언어별 구체적인 예외 처리 문법과 특징을 자세히 살펴본다.
2. 1. [[C++]]
C++에서는 `try`, `catch`, `throw` 키워드를 사용하여 예외를 처리한다. `try` 블록 안에서 예외가 발생할 가능성이 있는 코드를 실행하고, 예외가 발생하면 해당 예외 타입과 일치하는 `catch` 블록으로 제어가 넘어간다.
아래는 기본적인 예외 처리 구조 예시이다.
#include 
#include 
#include 
int main() {
    try {
        // 무언가를 수행 (예외를 발생시킬 수 있음)
        // 예: throw std::runtime_error("오류 발생!");
    }
    catch (const std::exception& e) { // std::exception 및 그 하위 클래스의 예외를 잡음
        // 예외 e 처리
        std::cerr << "예외 발생: " << e.what() << std::endl;
    }
    catch (...) { // 모든 종류의 예외를 잡음
        // 이전에 catch 블록에서 잡히지 않은 모든 예외를 잡음
        // 알 수 없거나 관련 없는 유형의 예외를 잡는 데 사용할 수 있음
        std::cerr << "알 수 없는 예외 발생!" << std::endl;
    }
    return 0; // main 함수는 일반적으로 int를 반환
}
C++ 표준 라이브러리는 `std::exception` 클래스와 이를 상속하는 다양한 예외 클래스들을 제공한다. 사용자 정의 예외 클래스도 `std::exception`을 상속하여 만들 수 있다. `catch (...)` 구문은 특정 타입으로 명시되지 않은 모든 종류의 예외를 잡는 데 사용된다.
또한 C++에서는 ''자원 획득은 초기화'' (RAII, Resource Acquisition Is Initialization) 기법을 사용하여 예외 발생 시에도 자원(메모리, 파일 핸들 등)이 안전하게 해제되도록 권장한다. 객체의 생성자에서 자원을 획득하고 소멸자에서 자원을 해제하는 방식이다.
C++는 의도적으로 `finally` 키워드를 지원하지 않는다.[1] 이는 RAII 패턴을 통해 자원 관리를 더 효과적으로 할 수 있다는 설계 철학에 따른 것이다.
2. 1. 1. Microsoft 전용 예외 처리
Microsoft 전용 예외 처리에는 두 가지 유형이 존재한다.2. 2. [[Java]]
Java에서는 예외 처리를 위해 `try`, `catch`, `finally` 키워드를 사용한다. 기본적인 구조는 다음과 같다.
try {
    // 예외가 발생할 수 있는 코드
    // 예시: throw new EmptyStackException();
} catch (ExampleException ee) {
    // ExampleException 타입의 예외가 발생했을 때 실행될 코드
} finally {
    // try 블록이나 catch 블록의 실행이 끝난 후 항상 실행되는 코드 (선택 사항)
    // 단, try나 catch 블록에서 System.exit()가 호출되면 실행되지 않을 수 있다.
}
`finally` 블록은 자바 가상 머신(JVM)이 종료되거나, `try` 또는 `catch` 블록 안에서 현재 스레드가 종료되는 경우, 또는 `System.exit()` 메소드가 호출되는 경우에는 실행되지 않을 수 있다.
2. 3. [[C#]]
C#에서는 `try`, `catch`, `finally` 키워드를 사용하여 예외 처리를 구현한다.
`try` 블록 안에는 예외가 발생할 가능성이 있는 코드를 위치시킨다. 모든 `try` 블록은 최소한 하나의 `catch` 블록 또는 `finally` 블록을 가져야 하며, `finally` 블록은 최대 하나만 포함할 수 있다.
`catch` 블록은 `try` 블록 내에서 발생한 예외를 잡아서 처리하는 역할을 한다. 특정 타입의 예외(Exception 클래스나 그 하위 클래스, 예를 들어 `HttpException`)를 명시하여 해당 종류의 예외만 처리하도록 할 수 있다. 또한, 특정 타입을 명시하지 않거나 `Exception` 타입을 사용하여 더 일반적인 예외를 처리하거나, 심지어 CLR 예외를 포함한 모든 종류의 예외를 처리하는 `catch` 블록을 작성할 수도 있다. 여러 개의 `catch` 블록을 사용하여 예외 종류별로 다른 처리 로직을 구현하는 것이 가능하다.
`finally` 블록은 `try` 블록의 실행이 정상적으로 완료되거나, `catch` 블록을 통해 예외가 처리된 후, 혹은 처리되지 않은 예외로 인해 블록을 벗어날 때 등 항상 실행되는 코드 영역이다. 예외 발생 여부나 처리 여부와 관계없이 실행되므로, 파일 핸들이나 네트워크 연결과 같이 사용 후 반드시 정리해야 하는 리소스를 해제하는 코드를 넣기에 적합하다. 단, System.Environment.FailFast 메서드가 호출되거나, 갑작스러운 전원 손실과 같은 시스템 전체의 예외 상황, 또는 다른 스레드에서 발생한 예외로 인해 현재 프로세스가 예기치 않게 중단되는 경우에는 `finally` 블록이 실행되지 않을 수도 있다.
아래는 C#에서 예외 처리를 사용하는 기본적인 코드 구조 예시이다.
public static void Main()
{
try
{
// 예외가 발생할 수 있는 코드를 이 안에 작성한다.
}
catch (HttpException ex) // 특정 예외 타입(HttpException) 처리
{
// HttpException 타입의 예외가 발생했을 때 실행된다.
// 발생한 예외 객체는 'ex'라는 이름의 변수에 저장되어 참조할 수 있다.
}
catch (Exception) // HttpException 외 다른 모든 CLR 예외 처리
{
// 위 catch 블록에서 잡지 못한 다른 모든 CLR(공통 언어 런타임) 예외를 처리한다.
// 이 경우, 예외 객체를 참조하기 위한 변수 이름이 지정되지 않았다.
}
catch // 모든 종류의 예외 처리 (CLR 예외 포함)
{
// 위 catch 블록들에서 처리되지 않은 모든 종류의 예외(비 CLR 예외 포함)를 처리한다.
}
finally // 항상 실행되는 블록
{
// try 블록의 실행이 끝나거나 catch 블록 실행 후 항상 실행된다.
// 예외 발생 여부나 처리 여부와 관계없이 실행된다. (매우 예외적인 시스템 종료 상황 제외)
// 파일 핸들 닫기 등 리소스 정리 작업에 주로 사용된다.
}
}
2. 4. [[Python]]
파이썬에서는 `try`, `except`, `else`, `finally` 키워드를 사용하여 예외를 처리한다. 다음은 예외 처리의 기본적인 구조를 보여주는 예시 코드이다.
f = None
try:
    # 예외 발생 가능성이 있는 코드
    f = open("aFileName", "w")
    f.write(could_make_error()) # 이 함수에서 예외가 발생할 수 있음
except IOError:
    # 특정 예외(IOError) 처리
    print("파일을 열 수 없습니다")
except:
    # 그 외 모든 예외 처리
    print("예상치 못한 오류")
else:
    # try 블록에서 예외가 발생하지 않았을 경우 실행
    print("파일 쓰기가 성공적으로 완료되었습니다")
finally:
    # 예외 발생 여부와 관계없이 항상 실행 (주로 자원 해제 등에 사용)
    if f:
        f.close()
(참고: 위 코드 예시에서 `could_make_error()` 함수는 예외를 발생시킬 수 있는 임의의 함수를 나타낸다.)
2. 5. [[JavaScript]]
JavaScript의 설계는 심각한 오류가 드물게 발생하도록 만들어졌다. 대신 덜 심각하거나 조용한 오류(소프트 에러)가 더 흔하게 나타난다. 심각한 오류는 가장 가까운 `try` 문으로 전파되며, `try` 문 다음에는 `catch` 절이나 `finally` 절, 또는 둘 다가 와야 한다.
try {
  // 예외가 발생할 수 있는 코드
  throw new Error("예시 오류"); // new Error 객체를 사용하여 오류를 발생시킴
} catch (error) { // 발생한 오류(error)를 매개변수로 받음
  // 예외가 발생했을 때 실행될 코드
  console.error("오류 발생:", error.message);
} finally {
  // try 블록의 코드 실행 결과와 관계없이 항상 실행될 코드
  console.log("예외 처리 시도 완료.");
}
만약 코드 내에 `try` 문이 없다면, 오류가 발생해도 웹 페이지가 중단되지는 않는다. 대신, 오류 정보가 브라우저의 개발자 콘솔에 기록되고 해당 실행 흐름(스택)은 중단된다.
JavaScript의 흥미로운 특징 중 하나는 비동기적으로 외부에서 코드가 호출될 수 있다는 점이다. 다른 많은 프로그래밍 언어와 달리, JavaScript 코드는 처음부터 끝까지 순차적으로만 실행되지 않는다. 예를 들어, 사용자의 클릭에 반응하는 이벤트 리스너, 특정 시간 후에 코드를 실행하는 타이머(`setTimeout`, `setInterval`), 또는 비동기 작업의 결과를 다루는 Promise 등은 나중에 브라우저에 의해 호출되어 실행될 수 있다. 이들은 코드의 나머지 부분과 분리되어 실행되지만, 같은 환경(컨텍스트)을 공유한다. 아래 코드는 `setInterval`을 사용하여 4초마다 새로운 오류를 계속 발생시키는 예시이다.
setInterval(function() {
  try {
    throw new Error("4초 간격으로 발생하는 오류의 예시입니다.");
  } catch (e) {
    console.error(e.message); // 오류를 콘솔에 기록하여 프로그램 중단 방지
  }
}, 4000);
JavaScript는 오류를 던질 때 다형성을 지원한다. 즉, 표준 `Error` 객체뿐만 아니라 숫자나 문자열 같은 원시(primitive) 값도 `throw` 키워드를 사용하여 던질 수 있다.
try {
  throw 12345; // 숫자를 오류로 던짐
} catch (error) {
  console.log("잡힌 오류:", error); // 콘솔에 숫자 12345가 기록됨
}
`catch` 절은 기본적으로 모든 유형의 오류를 잡는다. 특정 유형의 오류에 따라 다른 처리를 하기 위한 별도의 문법은 없다 (과거 Gecko 엔진의 실험적 확장 기능 제외). 대신, `catch` 블록 내에서 `if` 문을 사용하여 오류의 종류를 확인하거나(`instanceof` 연산자 사용), 오류를 처리할 수 없으면 다시 `throw` 하여 상위 스코프로 전파할 수 있다. 또는 `try...catch` 문을 중첩하여 사용할 수도 있다. Java와 비교하면 다음과 같다.
// Java 예시: catch 블록에서 특정 예외 타입을 명시
try {
  Integer i = null;
  i.intValue(); // NullPointerException 발생
} catch (NullPointerException error) {
  // NullPointerException 처리
} catch (ArithmeticException error) {
  // ArithmeticException 처리
}
// JavaScript 대안 1: instanceof 사용
try {
  let example = null;
  example.toString(); // TypeError 발생
} catch (error) {
  if (error instanceof TypeError) {
    console.log("타입 오류 발생:", error.message);
  } else if (error instanceof RangeError) {
    console.log("범위 오류 발생:", error.message);
  } else {
    // 처리할 수 없는 다른 오류는 다시 던짐
    throw error;
  }
}
// JavaScript 대안 2: 중첩 try...catch 사용
try {
  try {
    let example = null;
    example.toString(); // TypeError 발생
  } catch (error) {
    if (!(error instanceof TypeError)) {
      throw error; // TypeError가 아니면 다시 던짐
    }
    console.log("내부 catch: 타입 오류 처리");
  }
} catch (error) {
  // 여기서 다른 유형의 오류(예: RangeError)를 잡거나 처리할 수 있음
  if (!(error instanceof RangeError)) {
     throw error; // RangeError가 아니면 다시 던짐
  }
  console.log("외부 catch: 범위 오류 처리");
}
Promise는 비동기 작업 중 발생할 수 있는 예외를 처리하는 또 다른 방법을 제공한다. Promise의 `.catch()` 메서드를 사용하면 비동기 작업에서 발생한 오류를 처리할 수 있다. 이렇게 처리된 오류는 더 이상 바깥으로 전파되지 않는다.
new Promise((resolve, reject) => {
  throw new Error("Promise 내에서 발생한 오류!");
}).catch(err => {
  console.log("Promise 오류 잡음:", err.message);
});
또한, `unhandledrejection` 이벤트를 사용하여 코드 전역에서 처리되지 않은 Promise 거부(오류)를 감지하고 처리할 수도 있다.
// 이 이벤트 리스너는 처리되지 않은 Promise 거부가 발생할 때마다 호출됨
window.addEventListener("unhandledrejection", event => {
  console.warn("처리되지 않은 Promise 거부 발생:", event.reason);
  event.preventDefault(); // 브라우저의 기본 오류 처리(콘솔에 오류 로깅) 방지
});
new Promise(() => {
  throw new Error("이 오류는 위의 unhandledrejection 리스너에 의해 잡힙니다.");
});
마지막으로, JavaScript는 표시하고 쓸기(mark-and-sweep) 방식의 가비지 컬렉션을 사용한다. 이 때문에 `throw` 문을 사용하여 객체(심지어 순환 참조가 있는 객체)를 던지더라도, 해당 객체가 더 이상 참조되지 않으면 가비지 컬렉터가 자동으로 메모리를 회수하므로 메모리 누수가 발생하지 않는다.
try {
  const obj = {};
  obj.self = obj; // 자기 자신을 참조하는 순환 참조 생성
  throw obj; // 순환 참조가 있는 객체를 던짐
} catch (error) {
  console.log("순환 참조 객체를 오류로 잡음:", error);
  // 이 블록이 끝나면 obj는 더 이상 참조되지 않으므로 가비지 컬렉션 대상이 됨
}
2. 6. [[PHP]]
PHP에서는 버전 5부터 예외 처리를 위한 문법을 지원한다. 예외 처리는 `try`, `catch`, `finally` 키워드를 사용하여 이루어진다.
`try` 블록 안에는 예외가 발생할 가능성이 있는 코드를 작성한다. 만약 `try` 블록 내에서 예외 상황이 발생하면, `throw` 키워드를 사용하여 예외를 발생시킬 수 있다. 예외는 보통 `Exception` 클래스나 이를 상속받은 클래스의 인스턴스로 생성하여 던진다.
발생한 예외는 `catch` 블록에서 처리한다. `catch` 블록은 특정 타입의 예외를 받아서 처리하며, 여러 개의 `catch` 블록을 사용하여 다양한 종류의 예외에 대응할 수 있다.
`finally` 블록은 `try` 블록에서 예외가 발생했는지 여부와 관계없이 항상 실행되는 코드 블록이다. 주로 파일 핸들이나 데이터베이스 연결 해제와 같은 마무리 작업을 위해 사용된다.
아래는 PHP 예외 처리의 기본적인 사용 예시이다.
// 예외 처리는 PHP 버전 5 이상에서만 사용할 수 있습니다.
try {
    // 예외를 발생시킬 수 있는 코드
    throw new Exception('잘못된 URL.');
} catch (FirstExceptionClass $exception) {
    // 이 예외를 처리하는 코드
} catch (SecondExceptionClass $exception) {
    // 다른 예외를 처리하는 코드
} finally {
    // 예외 발생 여부에 관계없이 정리 작업을 수행합니다.
}
2. 7. [[Ruby]]
루비에서는 `begin`, `rescue`, `ensure` 키워드를 사용하여 예외를 처리한다.
begin
  # 예외가 발생할 수 있는 코드를 이 안에 작성한다.
  raise SomeError, "이것은 에러 메시지입니다!"  # raise 키워드로 예외를 발생시킨다.
rescue SomeError
  # SomeError 타입의 예외가 발생했을 때 실행된다.
rescue AnotherError => error
  # AnotherError 타입의 예외가 발생했을 때 실행된다.
  # 발생한 예외 객체는 error 변수를 통해 접근할 수 있다.
rescue
  # 특정 예외를 지정하지 않으면 StandardError 및 그 하위 클래스의 모든 예외를 처리한다.
  retry # begin 블록의 코드를 다시 실행한다.
else
  # begin 블록에서 예외가 발생하지 않았을 경우에만 실행된다.
ensure
  # 예외 발생 여부와 관계없이 항상 마지막에 실행된다.
  # 파일 닫기 등 마무리 작업을 주로 처리한다.
end2. 8. [[Swift]]
Swift에서는 버전 2부터 예외 처리를 지원한다. Swift의 예외 처리는 `do-catch` 구문을 기반으로 하며, 다음과 같은 키워드를 사용한다:
Swift에서는 열거형(enum)을 사용하여 사용자 정의 오류 타입을 정의하는 것이 일반적이다. 이 열거형은 `Error` 프로토콜(Swift 2에서는 `ErrorType`)을 준수해야 한다. `catch` 블록에서는 패턴 매칭을 사용하여 특정 오류 케이스를 구별하고, 필요한 경우 오류와 연관된 값을 추출하여 처리할 수 있다.
아래는 Swift 예외 처리의 예시 코드이다. `MyException`이라는 열거형을 정의하여 오류 타입을 나타내고, `someFunc` 함수에서 이 오류를 발생시킨다. `do-catch` 구문 내에서 `try`를 사용하여 `someFunc`를 호출하고, `catch` 블록에서 발생한 오류를 패턴 매칭을 통해 처리한다.
```swift
// Error 프로토콜(Swift 2에서는 ErrorType)을 따르는 열거형으로 오류 타입 정의
enum MyException : Error {
    case Foo(String, Int)
}
// throws 키워드로 예외를 던질 수 있음을 명시
func someFunc() throws {
    // throw 키워드로 예외 발생
    throw MyException.Foo("not enough food", 2)
}
// do-catch 구문으로 예외 처리
do {
    // try 키워드로 예외 발생 가능성이 있는 함수 호출
    try someFunc()
    print("Not reached") // 예외가 발생하면 이 줄은 실행되지 않음
} catch MyException.Foo(let s, let i) { // 패턴 매칭으로 특정 오류 처리
    print("MyException: \(s), \(i)")
} catch { // 모든 다른 종류의 예외 처리
    print("Unexpected exception : \(error)")
}
2. 9. 기타 언어
다양한 프로그래밍 언어들은 저마다 고유한 문법과 철학을 바탕으로 예외 처리 메커니즘을 구현하고 있다. 일부 언어는 `try-catch`와 유사한 구조를 통해 예외를 명시적으로 처리하는 반면, C와 같이 언어 차원의 직접적인 지원 없이 반환값 검사나 특정 라이브러리 함수(`setjmp`/`longjmp`)를 활용해야 하는 경우도 있다. 또한, 함수형 프로그래밍 언어 중 일부는 모나드와 같은 개념을 사용하여 오류 상황을 값으로 다루기도 한다.
아래에서는 여러 프로그래밍 언어에서 사용하는 구체적인 예외 처리 방식과 문법을 살펴본다. 각 언어의 설계 목표와 특성에 따라 예외를 정의하고, 발생시키며, 처리하는 방식에 차이가 있음을 확인할 수 있다.
2. 9. 1. [[Ada]]
Ada에서는 `exception` 키워드를 사용하여 예외를 선언하고, `raise` 키워드로 예외를 발생시킨다. 예외 처리는 `exception` 블록 내에서 `when` 키워드를 사용하여 수행한다.
'''예외 선언'''
다음과 같이 `exception` 키워드를 사용하여 사용자 정의 예외를 선언할 수 있다.
  Some_Error : exception;
'''예외 발생'''
`raise` 키워드를 사용하여 선언된 예외를 발생시킨다. 특정 진단 메시지와 함께 예외를 발생시킬 수도 있다.
  raise Some_Error;
  raise Some_Error with "Out of memory"; -- 특정 진단 메시지 포함
'''예외 처리 및 전파'''
`begin ... end` 블록 내에 `exception` 핸들러를 정의하여 예외를 처리할 수 있다. `when` 절을 사용하여 특정 예외나 `others`를 통해 나머지 모든 예외를 처리한다. 예외 핸들러 내에서 다른 예외를 다시 `raise`하여 예외를 전파하거나 변환할 수 있다. `Ada.Exceptions` 패키지를 사용하면 발생한 예외의 이름이나 메시지 같은 정보를 얻을 수 있다.
  with Ada.Exceptions, Ada.Text_IO;
  procedure Foo is
  Some_Error : exception;
  begin
  Do_Something_Interesting;
  exception -- 예외 핸들러 시작
  when Constraint_Error =>
  ... -- 제약 조건 오류 처리
  when Storage_Error =>
  raise Some_Error with "Out of memory";
  when Error : others =>
  Ada.Text_IO.Put("Exception: ");
  Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Name(Error));
  Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Message(Error));
  end Foo;
2. 9. 2. [[Assembly language]]
대부분의 어셈블리 언어는 특정 시스템에서 발생하는 예외적인 상황, 예를 들어 잘못된 명령어 실행 시도, 프로그램 검사 오류, 데이터 오류, 오버플로, 0으로 나누기와 같은 이벤트를 처리하기 위한 방법을 제공한다. 이는 주로 시스템별 매크로 명령어 또는 인터럽트 주소를 통해 구현된다.
예를 들어, 과거 IBM 및 유니백 메인프레임 컴퓨터에서는 STXIT 매크로를 사용했다. 디지털 이큅먼트 코퍼레이션(DEC)의 RT11 시스템은 프로그램 오류나 입출력 인터럽트 등을 처리하기 위한 트랩 벡터(trap vector)를 가지고 있었다. 개인용 컴퓨터 운영체제인 MS-DOS는 특정 인터럽트 주소를 예외 처리에 활용했으며, 마이크로소프트 윈도우는 프로그램 오류를 감지하고 처리하기 위한 특정 모듈 호출 방식을 사용한다.
2. 9. 3. [[ATS]]
ATS에서는 `exception` 키워드를 사용하여 새로운 예외 타입을 정의할 수 있다. 예외는 특정한 값을 함께 전달하는 데 사용될 수 있다. 예를 들어, 아래 코드에서는 문자열(`string`)과 정수(`int`) 값을 가지는 `MyException`이라는 이름의 예외를 정의한다.
예외 처리는 `try ... with` 구문을 통해 이루어진다. `try` 블록 내에서 예외가 발생할 가능성이 있는 코드를 실행하고, 만약 예외가 발생하면 `$raise` 키워드를 사용하여 예외를 명시적으로 던진다. 발생한 예외는 `with` 블록에서 패턴 매칭을 통해 처리된다.
아래는 ATS의 예외 처리 예시 코드이다.
exception MyException of (string, int) (* 예외는 값을 가질 수 있다 *)
implement main0 (): void =
  try
    $raise MyException("음식이 충분하지 않음", 2) (* MyException 예외를 문자열과 정수 값과 함께 발생시킨다 *)
  with
  | ~MyException(s, i) => begin (* 발생한 MyException 예외를 패턴 매칭으로 잡는다 *)
      (* 외부 C 함수인 fprintf를 호출하여 표준 오류(stderr)에 예외 메시지와 값을 출력한다 *)
      $extfcall(void, "fprintf", stderr_ref, "%s: %d", s, i);
      fileref_close(stderr_ref) (* 표준 오류 파일 참조를 닫는다 *)
    end
이 예제에서는 `try` 블록에서 `MyException` 예외를 "음식이 충분하지 않음"이라는 문자열과 숫자 2와 함께 발생시킨다. `with` 블록에서는 이 예외를 잡아(`~MyException(s, i)`), 예외에 포함된 문자열(`s`)과 정수(`i`) 값을 사용하여 C 언어의 표준 오류 출력 함수인 `fprintf`를 호출한다. 이를 통해 오류 메시지를 표준 오류 스트림에 출력하고, 마지막으로 파일 참조를 닫는다.
2. 9. 4. [[Bash]]
Bash 셸에서는 `trap` 내장 명령어를 사용하여 스크립트 실행 중 특정 신호(signal)를 받았을 때 지정된 동작을 수행하도록 설정할 수 있다. 이를 통해 기본적인 예외 처리를 구현하고, 스크립트가 예기치 않게 종료될 때 정리 작업을 수행하는 등의 용도로 활용된다.
예를 들어, 스크립트가 어떤 이유로든 종료될 때 (`EXIT` 신호) 특정 함수를 실행하거나 명령어를 수행하도록 설정할 수 있다. 다음은 `trap`을 사용한 예시 스크립트이다.
#!/usr/bin/env bash
# set -e는 오류 발생 시 스크립트를 즉시 종료하는 다른 오류 처리 메커니즘이다. (여기서는 주석 처리됨)
# 오류 발생 시 실행될 함수 정의
print_error(){
    echo "오류가 발생했습니다"
}
# 스크립트 종료 시(EXIT 신호) print_error 함수를 실행하도록 트랩 설정
trap print_error EXIT
# 임시 파일 생성 (`mktemp` 명령어 사용)
tempfile=$(mktemp) # 최신 Bash에서는 `` 대신 $() 사용 권장
# 스크립트 종료 시(EXIT 신호) 임시 파일을 삭제하도록 트랩 추가 설정
# 참고: 동일한 신호(EXIT)에 여러 trap을 설정하면 동작 방식(덮어쓰기 또는 순차 실행)이 Bash 버전에 따라 다를 수 있다.
# 일반적으로는 trap "명령어1; 명령어2" EXIT 와 같이 하나의 trap에 여러 명령을 묶는 것이 더 예측 가능하다.
trap "rm -f $tempfile" EXIT # -f 옵션 추가하여 파일이 없어도 오류 발생 방지
# ./other.sh 스크립트를 실행하고, 실패하면(||) 경고 메시지를 출력한다.
./other.sh || echo "경고: other.sh 실행 실패"
# 이 라인은 ./other.sh 실행 결과와 관계없이 실행될 수 있다.
# (단, set -e 가 활성화된 상태에서 ./other.sh가 실패하면 스크립트는 여기서 즉시 종료된다.)
echo "스크립트 진행 중..."
# 원본 소스의 'echo oops)' 와 'echo never printed' 는 trap 동작 설명을 위한 예시로 보이며,
# 실제 스크립트의 흐름이나 set -e 활성화 여부, other.sh의 성공/실패 여부에 따라
# 이 부분의 코드가 실행될 수도, 실행되지 않을 수도 있다.
# 스크립트가 정상적으로든, 오류로든 종료되면 설정된 EXIT 트랩이 발동된다.
# 위 예제에서는 최종적으로 print_error 함수가 호출되고, 임시 파일 $tempfile 이 삭제된다.
또한, 스크립트 내에서 명령어가 실패하여 오류가 발생했을 때(`ERR` 신호) 특정 동작을 수행하도록 트랩을 설정할 수도 있다. 예를 들어, 오류가 발생한 소스 코드 라인 번호(`$LINENO` 변수)를 출력하도록 설정하는 구문은 다음과 같다.
trap 'echo "${LINENO} 라인에서 오류 발생"' ERR
이처럼 `trap` 명령어는 Bash 스크립트의 오류 처리 및 자원 관리에 유용하게 사용될 수 있다.
2. 9. 5. [[BASIC]]
BASIC에서는 ''On Error goto'' 구문을 사용하여 예외를 처리한다. 이는 현대적인 예외 처리와는 차이가 있는데, BASIC에서는 하나의 전역 핸들러만 존재하는 반면, 현대적인 예외 처리에서는 예외 핸들러가 스택으로 구성된다.
아래는 `ON ERROR GOTO`를 사용한 예제 코드이다.
ON ERROR GOTO handler          ' 오류 발생 시 handler 레이블로 이동하도록 설정한다.
OPEN "Somefile.txt" FOR INPUT AS #1 ' "Somefile.txt" 파일을 읽기 모드로 연다.
CLOSE #1                       ' 파일 핸들 #1을 닫는다.
PRINT "File opened successfully" ' 파일 열기 성공 메시지를 출력한다.
END                            ' 프로그램 실행을 종료한다.
handler:                       ' 오류 처리 코드 시작 레이블이다.
PRINT "File does not exist"    ' 파일이 존재하지 않는다는 오류 메시지를 출력한다.
END                            ' 프로그램 실행을 종료한다. (주석: RESUME을 대신 사용하여 원래 위치로 제어 흐름을 반환할 수도 있다.)
2. 9. 6. [[C]]
C는 예외 처리를 직접적으로 지원하지 않는다. 오류를 사전에 방지하고 함수의 반환값을 검사하는 것은 프로그래머의 책임이다.
표준 C에서 예외 처리를 구현하는 한 가지 방법은 setjmp.h 헤더 파일에 정의된 `setjmp`와 `longjmp` 함수를 사용하는 것이다. `setjmp` 함수는 현재 실행 상태(레지스터 값, 프로그램 카운터 등)를 `jmp_buf` 타입의 버퍼에 저장하고, 처음 호출될 때는 0을 반환한다. `longjmp` 함수는 이전에 `setjmp`로 저장된 상태로 프로그램의 실행 흐름을 강제로 되돌린다. 이때 `longjmp`의 두 번째 인자로 전달된 값이 `setjmp` 함수의 반환값이 되며, 이 값은 0이 아니어야 한다. 이를 이용하여 `try-catch`와 유사한 예외 처리 구조를 만들 수 있다.
아래는 `setjmp`와 `longjmp`를 이용한 예외 처리 예제 코드이다.
#include 
#include 
#include 
// 예외 타입을 나타내는 열거형 정의
enum { NO_EXCEPTION = 0, SOME_EXCEPTION = 1 };
// 예외 상태를 저장할 변수
int exception_type = NO_EXCEPTION;
// 프로그램 실행 상태를 저장할 버퍼
jmp_buf state;
int main(void)
{
    // setjmp 호출: 현재 상태를 'state' 버퍼에 저장.
    // 처음 호출 시 0을 반환하여 if 블록 실행 (try 블록 역할).
    // longjmp 호출로 이 지점으로 돌아오면 longjmp의 두 번째 인자 값을 반환.
    if (setjmp(state) == NO_EXCEPTION)
    {
        // 예외가 발생할 수 있는 코드 영역
        printf("try 블록 실행 중...\n");
        // 특정 조건에서 예외 발생 시뮬레이션
        int error_condition = 1; // 예: 오류 조건 발생
        if (error_condition)
        {
            printf("예외 발생! longjmp 호출.\n");
            exception_type = SOME_EXCEPTION; // 발생한 예외 종류 기록
            longjmp(state, SOME_EXCEPTION);  // 저장된 'state' 위치로 점프 (예외 던지기 역할)
                                             // 두 번째 인자(SOME_EXCEPTION)가 setjmp의 반환값이 됨
        }
        // 예외가 발생하지 않으면 실행될 코드
        printf("정상적으로 실행 완료.\n");
    }
    else // longjmp에 의해 이 위치로 점프했을 경우 실행됨 (catch 블록 역할)
    {
        // setjmp의 반환값(longjmp의 두 번째 인자) 또는 저장된 예외 타입(exception_type)을 확인하여 처리
        switch(exception_type) // 또는 switch(setjmp(state)) 로 직접 사용 가능 (단, longjmp의 두번째 인자가 0이 아니어야 함)
        {
            case SOME_EXCEPTION:        // SOME_EXCEPTION 처리
                printf("SOME_EXCEPTION 예외가 잡혔습니다.\n");
                break;
            default:                    // 그 외 예외 처리
                printf("알 수 없는 예외가 잡혔습니다.\n");
        }
    }
    printf("프로그램 종료.\n");
    return EXIT_SUCCESS;
}
2. 9. 7. [[ColdFusion Markup Language|CFML]]
wikitext
try {
    // CF9 이상: 예외 발생시키기
    // type: 예외 유형 지정
    // message: 예외 메시지
    // detail: 예외 상세 정보
    throw(type="TypeOfException", message="이런", detail="xyz");
    // 다른 throw 구문 (메시지만 지정):
    // throw "이런"; // 위 예제의 "message" 값과 동일
} catch (any e) {
    // 발생한 예외 잡기 및 처리
    writeOutput("오류: " & e.message); // 예외 메시지 출력
    rethrow; // 잡은 예외를 다시 상위로 던지기 (CF9 이상)
} finally { // CF9 이상: 예외 발생 여부와 관계없이 항상 실행
    writeOutput("오류가 없더라도 실행됩니다");
}
어도비 콜드퓨전 문서[2]
CFML 태그를 사용하여 예외를 처리할 때는 `cftry`, `cfcatch`, `cffinally` 태그를 사용한다. `cftry` 블록 안에는 예외가 발생할 수 있는 코드를 작성하고, `cfcatch` 블록에서는 발생한 예외를 잡아 처리한다. `cfcatch` 태그의 `type` 속성을 사용하여 특정 유형의 예외만 잡거나, `Any`를 지정하여 모든 유형의 예외를 잡을 수 있다. `cffinally` 블록은 `cftry` 블록 내 코드의 실행 결과(성공, 예외 발생 등)와 관계없이 항상 마지막에 실행된다. `cftry` 블록은 아래 예시처럼 중첩하여 사용할 수도 있다.
    
    
        
        
            
            
                
            
            
                
            
        
    
    
         
    
Railo나 Lucee와 같은 일부 CFML 엔진에서는 표준 문법 외에 `retry` (태그 형식: `cfretry`) 구문을 추가로 지원한다.[4] 이 구문은 `catch` 블록 안에서 사용되며, 실행되면 해당 `try` 블록의 처음으로 돌아가 코드를 다시 실행하도록 한다.
CFScript에서의 `retry` 사용 예시:
try {
    // 예외가 발생할 수 있는 코드
} catch (any e) {
    // 예외 처리 로직 수행 후
    retry; // try 블록 처음부터 재시도
}
태그 기반 구문에서의 `cfretry` 사용 예시:
    
    
        
        
    
2. 9. 8. [[D]]
wikitext
import std.stdio; // writefln() 함수를 위해
int main() {
    try {
        // 예외를 발생시킬 수 있는 작업 수행
    }
    catch (FooException e) {
        // FooException 타입의 예외 처리
    }
    catch (Object o) {
        // 다른 모든 예외 처리
        writefln("처리되지 않은 예외: ", o);
        return 1;
    }
    return 0;
}
D에서는 `finally` 절 또는 자원 획득은 초기화 기법을 사용하여 예외 상황에서 자원을 정리할 수 있다.
2. 9. 9. [[Delphi]]
; 예외 선언
델파이에서 예외는 `Exception` 클래스를 상속받아 선언한다. 사용자 정의 데이터를 포함하는 예외 클래스를 만들 수 있다.
type ECustom = class(Exception) // 예외는 Exception 클래스의 자식이다.
private
  FCustomData: SomeType;      // 예외는 사용자 지정 확장을 가질 수 있다.
public
  constructor CreateCustom(Data: SomeType); // 구현이 필요하다.
  property CustomData: SomeType read FCustomData; // CustomData 프로퍼티
end;
; 예외 발생
`raise` 키워드를 사용하여 예외를 발생시킨다. `Create` 메소드로 간단한 메시지와 함께 예외를 발생시키거나, `CreateFmt` 메소드를 사용하여 포맷 문자열과 값으로 메시지를 구성할 수 있다. 사용자 정의 예외 클래스의 인스턴스를 생성하여 발생시킬 수도 있다.
raise Exception.Create('메시지');
// SysUtils.Format() 함수와 유사하게 매개변수를 사용하여 메시지 포맷 지정
raise Exception.CreateFmt('값 포함 메시지: %d, %d', [value1, value2]);
raise ECustom.CreateCustom(X); // 사용자 정의 예외 발생
; 예외 처리 및 전파[5]
`try...except` 블록으로 예외를 처리하고, `try...finally` 블록으로 예외 발생 여부와 관계없이 항상 실행되어야 하는 코드를 작성한다. `except` 블록 내에서 `on` 키워드를 사용하여 특정 타입의 예외를 구분하여 처리할 수 있다. 처리 중 다른 예외를 발생시키거나(`raise EYetAnotherException.Create(...)`), 현재 예외를 다시 발생시켜 상위 호출 스택으로 전파(`raise;`)할 수 있다.
try // finally 블록 시작
  try // except 블록 시작
    ... // 예외가 발생할 수 있는 코드
  except
    on C:ECustom do // ECustom 타입의 예외 처리
    begin
      ... // ECustom 예외 처리 로직
      ... if Predicate(C.CustomData) then ...
    end;
    on S:ESomeOtherException do // ESomeOtherException 타입의 예외 처리
    begin
      // 다른 예외로 변환하여 전파
      raise EYetAnotherException.Create(S.Message);
    end;
    on E:Exception do // 나머지 모든 Exception 타입의 예외 처리
    begin
      ... // 기타 예외 처리 로직
      raise; // 현재 예외를 다시 발생시켜 전파
    end;
  end; // except 블록 끝
finally
  // 예외 발생 여부와 관계없이 항상 실행되는 코드 (예: 자원 해제)
end; // finally 블록 끝
2. 9. 10. [[Erlang]]
Erlang에서는 `try`, `catch`, `after` 키워드를 사용하여 예외를 처리한다.
`try` 블록 안에는 예외가 발생할 가능성이 있는 코드를 넣는다. 만약 이 코드 실행 중 예외가 발생하면, 프로그램 실행 흐름은 `catch` 블록으로 이동한다. `catch` 블록에서는 패턴 매칭을 이용해 발생한 예외의 종류(`throw`, `error` 등)에 따라 적절한 처리를 수행할 수 있다. `_:_` 패턴은 아직 처리되지 않은 모든 종류의 예외를 잡아내는 역할을 한다.
`after` 블록은 `try` 블록의 코드가 성공적으로 완료되거나, `catch` 블록에서 예외 처리가 끝난 후에 항상 실행된다. 이 부분은 주로 파일 닫기나 메모리 해제와 같이 반드시 수행되어야 하는 마무리 작업을 넣는 데 사용된다.
아래는 Erlang 예외 처리의 기본적인 구조를 보여주는 예시이다.
try
% 예외 발생 가능성이 있는 코드
catch
throw:{someError, X} -> ok;    % 특정 throw 예외 처리
error:X -> ok;                 % error 예외 처리
_:_ -> ok                      % 그 외 모든 예외 처리
after
% 예외 발생 여부와 관계없이 항상 실행되는 정리 작업
end
2. 9. 11. [[F#]]
OCaml 기반의 `try...with` 외에도 F#은 다른 .NET 언어의 `finally` 절이 있는 `try` 블록과 동일한 동작을 하는 별도의 `try...finally` 구문을 가지고 있다.
비교를 위해, 다음은 위의 C# 샘플의 번역이다.
```fsharp
try
    try
        () (* 예외를 발생시킬 수 있는 코드. *)
    with
    | :? System.Net.WebException as ex -> () (* WebException을 처리합니다. 예외 객체는 "ex"에 저장됩니다. *)
    | :? exn -> () (* 모든 CLR 예외를 처리합니다. 예외에 식별자가 지정되지 않았으므로 참조할 수 없습니다. *)
    | _ -> () (* CLR 예외가 아닌 것을 포함하여 발생할 수 있는 모든 것을 처리합니다. *)
finally
    ()
    (*
    try 블록을 벗어날 때 항상 실행되며, 예외가 발생했는지 여부나 처리되었는지 여부에 관계없이 실행됩니다.
    파일 핸들과 같은 리소스를 정리하고 닫는 데 자주 사용됩니다.
    Environment.FailFast()가 호출될 때와 기타 시스템 전체의 예외적인 조건(예: 전원 손실) 또는 다른 스레드의 예외로 인해 프로세스가 충돌할 때는 실행되지 않을 수 있습니다.
```
비교를 위해, 다음은 아래 OCaml 샘플의 번역이다.
```fsharp
exception MyException of string * int (* 예외는 값을 가질 수 있습니다 *)
let _ =
    try
        raise (MyException ("음식 부족", 2));
        printfn "도달하지 않음"
    with
    | MyException (s, i) ->
        printf "MyException: %s, %d\n" s i
    | e ->  (* 모든 예외 잡기 *)
        eprintf "예상치 못한 예외 : %O" e;
        eprintf "%O" e.StackTrace
2. 9. 12. [[Haskell]]
Haskell은 예외 처리를 위한 특별한 구문을 가지고 있지 않다. 대신 함수를 통해 `try`/`catch`/`finally` 등의 인터페이스가 제공된다.
다음은 예외 처리 예시 코드이다.
```haskell
import Prelude hiding(catch)
import Control.Exception
instance Exception Int
instance Exception Double
main = do
catch
(catch
(throw (42::Int))
(\e-> print (0,e::Double)))
(\e-> print (1,e::Int))
```
위 코드는 다음과 같이 출력된다.
 (1,42)
이는 다음과 같은 C++ 코드와 유사하게 동작한다.
```cpp
#include 
using namespace std;
int main()
{
try
{throw (int)42;}
catch(double e)
{cout << "(0," << e << ")" << endl;}
catch(int e)
{cout << "(1," << e << ")" << endl;}
}
```
`catch` 함수를 사용하는 또 다른 예시는 다음과 같다.
```haskell
do {
} `catch` \ex -> do {
}
```
순수 함수형 코드에서는 하나의 오류 조건만 존재하는 경우, `Maybe` 타입으로 충분할 수 있다. `Maybe` 타입은 기본적으로 Haskell의 Monad 타입 클래스의 인스턴스이다. 더 복잡한 오류 전파는 `Error` 또는 `ErrorT` 모나드를 사용하여 처리할 수 있으며, 이들 모나드에 대해서도 `catch`를 사용하는 유사한 기능이 지원된다.
2. 9. 13. [[Common Lisp]]
Common Lisp에서는 예외 처리를 위해 다양한 매크로를 제공한다.
`ignore-errors` 매크로는 코드 실행 중 발생하는 오류를 무시한다. 오류가 발생하면 `nil`과 오류 조건을 반환하고 프로그램 실행을 계속한다. 예를 들어, 0으로 나누는 연산을 시도할 때 오류가 발생해도 프로그램이 중단되지 않는다.
(ignore-errors (/ 1 0))
`handler-case` 매크로는 특정 코드 블록 내에서 발생할 수 있는 오류를 종류별로 처리하는 데 사용된다. try-catch 구문과 유사하게 작동한다. 아래 예시에서는 사용자로부터 수식을 입력받아 평가(`eval`)하는 과정에서 발생하는 모든 종류의 오류(`error`)를 잡아 해당 오류 객체(`e`)를 출력한다.
(handler-case
(progn
(print "수식을 입력하세요")
(eval (read)))
(error (e) (print e)))
`unwind-protect` 매크로는 특정 코드 블록이 실행된 후, 성공적으로 완료되었는지 또는 오류로 인해 중단되었는지 여부와 관계없이 반드시 실행되어야 하는 코드를 지정할 때 사용된다. 이는 try-finally 구문의 `finally` 블록과 비슷한 역할을 한다. 아래 예시에서는 수식 평가가 성공하든 실패하든 상관없이 항상 마지막 `print` 구문이 실행된다.
(unwind-protect
(progn
(print "수식을 입력하세요")
(eval (read)))
(print "이 부분은 finally와 유사하게 항상 실행됩니다."))
2. 9. 14. [[Lua]]
Lua는 예외 처리를 위해 pcall과 xpcall 함수를 사용한다. 이 중 xpcall은 오류 처리 함수를 인자로 받아, 오류 발생 시 해당 함수를 호출하여 C++의 catch 블록과 유사한 역할을 수행하게 할 수 있다.
=== pcall 사용 예시 ===
==== 미리 정의된 함수 사용 ====
미리 정의된 함수를 pcall로 호출하여 예외를 처리할 수 있다. pcall은 호출된 함수가 성공적으로 실행되었는지 여부(불리언 값)와 함수의 반환값 또는 오류 메시지를 반환한다.
function foo(x)
  if x then
    return x -- 인자가 참(true)이면 그대로 반환
  else
    error("참 값이 아님") -- 인자가 거짓(false)이면 오류 발생
  end
end
function attempt(arg)
  local success, value = pcall(foo, arg)
  if not success then
    print("오류: " .. tostring(value))
  else
    print("반환값: " .. tostring(value))
  end
end
attempt("hello") -- 성공: 문자열은 Lua에서 참으로 간주됨
attempt(nil) -- 실패: nil은 거짓으로 간주되어 error 발생
attempt({}) -- 성공: 테이블은 Lua에서 참으로 간주됨
if foo(42) then print "성공" end
==== 익명 함수 사용 ====
익명 함수를 pcall의 인자로 직접 전달하여 특정 코드 블록의 예외를 처리할 수도 있다.
if pcall(
  function()
    print("보호된 코드 블록 실행됨")
  end)
then
  print "오류 없음"
else
  print "오류 발생"
end
print "완료"
2. 9. 15. [[Next Generation Shell]]
사용자 정의 예외 유형 정의`type` 키워드를 사용하여 기존 `Error` 타입을 상속받는 새로운 예외 타입을 정의할 수 있다.
type MyError(Error)
예외 발생시키기`throw` 키워드를 사용하여 정의된 예외 타입의 인스턴스를 생성하고 발생시킨다.
throw MyError("this happened")
예외 처리 및 전파`try-catch` 블록을 사용하여 예외를 처리한다. 특정 타입의 예외(`MyError`)를 잡아 처리하거나, 더 일반적인 `Error` 타입으로 모든 예외를 처리할 수 있다. `catch` 블록 내에서 `guard` 키워드를 사용하여 특정 조건을 만족하는 예외만 선별적으로 처리하는 것도 가능하다. 처리되지 않은 예외는 상위 호출 스택으로 전파된다.
try {
# 예외가 발생할 수 있는 코드
} catch(e:MyError) {
guard e.val = 7 # MyError 타입이면서 val 속성이 7인 경우만 처리
# 예외 처리 로직...
} catch(e:MyError) {
# 다른 MyError 타입 예외 처리 로직...
} catch(e:Error) {
# 그 외 모든 Error 타입 예외 처리 로직...
}
예외 무시 - catch 절 없는 try`try` 블록만 사용하고 `catch` 절을 생략하면, 해당 블록 내에서 발생하는 예외는 조용히 무시되며 전체 표현식은 `null` 값으로 평가된다.
try 1/0  # 0으로 나누기 예외가 발생하지만 무시되어 null로 평가됨
예외 무시 - "tor" 연산자"tor"는 "try-or" 연산자로, 왼쪽 피연산자를 평가하는 동안 예외가 발생하면 해당 예외를 무시하고 오른쪽 피연산자를 평가하여 그 결과를 반환한다. 예외가 발생하지 않으면 왼쪽 피연산자의 결과가 반환된다.
1/0 tor 20  # 1/0 에서 예외가 발생하므로 무시하고 오른쪽 피연산자인 20을 평가하여 반환함 (결과: 20)
"block" - 값을 반환하기 위해 예외를 사용하는 기능`block`은 특정 코드 블록을 실행하고 값을 반환하는 구조이다. 블록 내에서 `블록이름.return(값)` 구문을 사용하면, 현재 실행 흐름을 즉시 중단하고 지정된 값을 `block` 표현식의 최종 결과로 반환한다. 이는 마치 예외를 발생시켜 특정 지점으로 점프하는 것과 유사하게 동작하며, 중첩된 제어 구조에서 값을 반환할 때 유용하게 사용될 수 있다.
my_result = block my_block {  # "block"은 아래의 my_block.return 호출을 잡아 값을 반환한다.
# 여러 계산 수행
if calculation_finished() {
my_block.return(42)  # 즉시 block을 빠져나가며 42를 my_result에 할당한다.
}
# calculation_finished()가 false이면 다른 로직 수행 후 block이 종료될 수 있다.
}
2. 9. 16. [[Objective-C]]
Objective-C에서는 `@try`, `@catch`, `@finally`, `@throw` 키워드를 사용하여 예외 처리를 수행한다.
'''예외 선언'''
NSException 클래스를 사용하여 예외 객체를 생성한다. `exceptionWithName:reason:userInfo:` 메서드를 통해 예외의 이름, 이유, 추가 정보를 설정할 수 있다.
```objc
NSException *exception = [NSException exceptionWithName:@"myException"
                                                 reason:@"yourReason"
                                               userInfo:nil];
```
'''예외 발생'''
`@throw` 키워드를 사용하여 생성된 예외 객체를 던진다.
```objc
@throw exception;
```
'''예외 처리 및 전파'''
`@try` 블록 안에 예외가 발생할 수 있는 코드를 넣는다. `@catch` 블록에서는 발생한 예외를 잡아 처리한다. `@catch` 블록은 특정 예외 타입(`SomeException *se`), 일반적인 NSException 타입(`NSException *ne`), 또는 모든 타입의 객체(`id ue`)를 잡을 수 있도록 여러 개를 사용할 수 있다. `@catch` 블록 내에서 `@throw;`를 사용하면 현재 처리 중인 예외를 다시 상위 호출자에게 전파할 수 있다. `@finally` 블록은 `@try` 블록의 코드 실행 후 예외 발생 여부와 관계없이 항상 실행되며, 주로 자원 해제 등의 정리 코드를 넣는다.
```objc
@try {
    // 예외 발생 가능성이 있는 코드
    ...
}
@catch (SomeException *se) {
    // SomeException 타입의 예외 처리
    ...
}
@catch (NSException *ne) {
    // 일반적인 NSException 타입의 예외 처리
    ...
    // 예외를 상위 수준으로 다시 던져서 전파
    @throw;
}
@catch (id ue) {
    // 다른 모든 타입의 던져진 객체 처리
    ...
}
@finally {
    // 예외 발생 여부와 관계없이 항상 실행되는 정리 코드
    ...
}
2. 9. 17. [[OCaml]]
OCaml에서는 `exception` 키워드를 사용하여 새로운 예외 타입을 정의할 수 있다. 예외는 특정 값을 가질 수도 있다. 예외를 발생시킬 때는 `raise` 키워드를 사용하고, 예외 처리는 `try ... with` 구문을 통해 이루어진다. `with` 절에서는 패턴 매칭을 사용하여 특정 예외를 잡아 처리하거나, 모든 종류의 예외를 처리할 수 있다.
다음은 OCaml 예외 처리의 예시 코드다.
```ocaml
(* 'string'과 'int' 타입의 값을 가지는 새로운 예외 'MyException' 정의 *)
exception MyException of string * int
let _ =
  try
    (* "음식 부족" 메시지와 숫자 2를 가진 MyException 예외 발생 *)
    raise (MyException ("음식 부족", 2));
    (* 예외가 발생하면 이 부분은 실행되지 않음 *)
    print_endline "도달하지 않음"
  with
  (* MyException 예외를 잡아 처리 (패턴 매칭 사용) *)
  | MyException (s, i) ->
    Printf.printf "MyException 발생: %s, %d\n" s i
  (* 그 외 모든 예외를 변수 'e'로 잡아서 처리 *)
  | e ->
    Printf.eprintf "예상치 못한 예외: %s\n" (Printexc.to_string e);
    (* OCaml 3.11 이상: 백트레이스(호출 스택) 출력 가능 *)
    Printexc.print_backtrace stderr;
    (* 백트레이스 기록은 미리 활성화 필요:
       코드에서 Printexc.record_backtrace true 호출 또는
       환경 변수 OCAMLRUNPARAM="b1" 설정 *)
2. 9. 18. [[Perl]]
Perl의 예외 처리 메커니즘은 `die` 함수를 사용하여 예외를 발생시키고, 이를 `eval { ... };` 블록으로 감싸서 처리하는 방식이다. `eval` 블록 실행 후에는 특수 변수 `$@`에 `die` 함수에서 전달된 값(예외 메시지 또는 객체)이 저장된다.
기본적인 예외 처리 형태는 다음과 같다.
my ( $error, $failed );
{
  local $@; # $@ 변수를 지역 변수로 선언하여 외부 영향 최소화
  $failed = not eval {
    # 예외가 발생할 수 있는 코드 ('die' 사용)
    open(my $fh, '<', $file) || die "파일을 열 수 없습니다: $!";
    while (<$fh>) {
      process_line($_);
    }
    close($fh) || die "$file 파일을 닫을 수 없습니다: $!";
    return 1; # 성공 시 참 반환
  };
  $error = $@; # 발생한 예외 저장
}
if ( $failed ) {
  warn "오류 발생: $error"; # 예외 처리
}
Perl 5.005 버전부터는 기존의 문자열 외에 객체(Object)도 예외로 던질(throw) 수 있게 되었다. 이를 통해 예외의 종류를 더 명확하게 구분하고 처리하는 것이 가능해졌다.
eval {
  open(my $fh, '<', $file) || die MyException::File->new($!); # 파일 관련 예외 객체 생성 및 던지기
  while (<$fh>) {
    process_line($_);
  }
  close($fh) || die MyException::File->new($!); # 파일 닫기 관련 예외 객체 생성 및 던지기
};
if ($@) {
  # 예외 객체는 $@ 변수에 저장됨
  if ($@->isa('MyException::File')) {
    # 파일 관련 예외 처리
  } else {
    # 일반적인 예외 처리
    # 또는 'die $@'를 사용하여 예외를 다시 던질 수 있음
  }
}
`__DIE__` 의사 시그널 핸들러를 설정하여 `die` 호출을 가로챌 수도 있다. 하지만 이 핸들러는 전역적으로 작동하기 때문에 일반적인 예외 처리 방식으로는 적합하지 않다. 주로 외부 라이브러리 등에서 발생하는 문자열 기반 예외를 특정 예외 객체로 변환하는 용도로 사용될 수 있다.
local $SIG{__DIE__} = sub {
  my $err = shift;
  if (ref($err) && $err->isa('MyException')) { # 이미 MyException 객체인 경우
    die $err; # 그대로 다시 던짐
  } else {
    # 그 외의 경우(주로 문자열 예외) MyException 객체로 변환하여 던짐
    die MyException::Default->new($err);
  }
};
`eval` 블록 실행 후 `if ($@)` 구문으로 예외 발생 여부를 확인하는 방식은, 다중 스레드 환경이나 특정 상황(예: 객체 소멸자 실행)에서 `$@` 변수의 값이 예기치 않게 변경될 수 있어 문제가 발생할 가능성이 있다. 이 문제를 피하기 위해 `eval { ... } or do { ... }` 구문을 사용할 수 있다. 이 방식은 `eval` 블록의 반환 값을 사용할 수 없다는 단점이 있다. (Stack Overflow 설명, ''cf''. 관련 논의).
eval {
  # 예외가 발생할 수 있는 코드 (단, return 문 사용 불가)
  # ...
  1; # 성공 시 참 값 반환 (필수)
} or do {
  # 예외 처리 코드. 예외 메시지는 $@에 저장됨
  my $error = $@;
  warn "오류 발생: $error";
};
CPAN(종합 Perl 아카이브 네트워크)에는 Perl의 기본 예외 처리 기능을 확장하는 다양한 모듈들이 존재한다.Error''': 다양한 예외 클래스를 제공하며, `try/throw/catch/finally` 구문을 사용할 수 있게 해준다.TryCatch''', '''Try::Tiny''', '''Nice::Try''': `try/catch/finally` 구문을 사용하여 예외 처리를 위한 상용구 코드 작성을 줄여준다.Exception::Class''': 예외 클래스를 쉽게 만들 수 있도록 도와주는 기본 클래스 및 클래스 생성 도구이다. `$@->trace`나 `$@->trace->as_string`을 통해 구조화된 스택 추적 정보를 제공한다.Fatal''': `open`, `close`, `read`, `write` 등 기존에 성공/실패 여부를 반환하던 내장 함수들을 오버로드하여, 실패 시 예외를 발생시키도록 동작을 변경한다.2. 9. 19. [[PowerBuilder]]
파워빌더에서는 8.0 버전 이상부터 예외 처리를 지원한다. 기본적인 구조는 다음과 같다.
TRY
    // 일반적인 실행 경로
CATCH (ExampleException ee)
    // ExampleException 처리
FINALLY
    // 위의 try 또는 catch 블록 종료 시 실행되는 선택적 섹션
END TRY
2. 9. 20. [[PowerShell]]
PowerShell에서는 `trap` 문이나 `Try`, `Catch`, `Finally` 블록을 사용하여 예외 처리를 수행할 수 있다.
`trap` 문은 스크립트나 함수 내에서 특정 유형의 예외가 발생했을 때 실행될 코드를 정의하는 오래된 방식이다.
trap [System.Exception] # 처리할 예외 유형을 지정한다. 생략하면 모든 예외를 처리한다.
{
    # 예외가 발생했을 때 실행할 코드 블록
    Write-Error "오류 발생: $($_.Exception.Message)"
    # Continue # 예외 처리 후 스크립트 실행을 계속하려면 사용
    # Break # 예외 처리 후 스크립트 실행을 중단하려면 사용 (기본값)
}
# 예외가 발생할 가능성이 있는 코드
throw "테스트 예외 발생"
Write-Host "이 메시지는 Break 사용 시 표시되지 않음"
최신 버전의 PowerShell에서는 다른 프로그래밍 언어와 유사한 `Try`, `Catch`, `Finally` 블록을 사용하는 것이 더 일반적이다. `Try` 블록 안에는 예외가 발생할 수 있는 코드를 넣고, `Catch` 블록에서는 발생한 예외를 종류별로 처리할 수 있다. `Finally` 블록은 예외 발생 여부와 관계없이 항상 실행되는 코드를 넣는다 (주어진 원본 소스에는 `Finally` 예시가 포함되어 있지 않다).
Try {
    # 예외가 발생할 가능성이 있는 코드
    Import-Module ActiveDirectory -ErrorAction Stop # 모듈 로딩 시 오류가 발생하면 예외를 던지도록 설정
    Write-Host "Active Directory 모듈 로드 성공"
}
Catch [Microsoft.PowerShell.Commands.ModuleNotFoundException] {
    # ModuleNotFoundException 예외가 발생했을 때 실행될 코드
    Write-Warning "Active Directory 모듈을 찾을 수 없습니다."
}
Catch [System.Management.Automation.CmdletInvocationException] {
    # CmdletInvocationException 예외가 발생했을 때 실행될 코드
    Write-Warning "명령 실행 중 오류 발생: $($_.Exception.Message)"
}
Catch {
    # 위에서 명시적으로 처리되지 않은 다른 모든 종류의 예외가 발생했을 때 실행될 코드
    Write-Error "알 수 없는 오류 발생: $($_.Exception.GetType().FullName) - $($_.Exception.Message)"
}
Finally {
    # 예외 발생 여부와 관계없이 항상 실행될 코드 (예: 리소스 정리)
    Write-Host "예외 처리 블록 실행 완료."
}
`Catch` 블록은 특정 예외 유형을 지정하여 처리하거나, 여러 예외 유형을 쉼표(`,`)로 구분하여 함께 처리할 수 있다. 아무 유형도 지정하지 않은 `Catch` 블록은 명시적으로 처리되지 않은 모든 유형의 예외를 처리하는 역할을 한다.
2. 9. 21. [[R]]
R에서는 `tryCatch` 함수를 사용하여 예외를 처리할 수 있다. 이 함수는 실행할 코드 블록과 발생할 수 있는 다양한 조건(에러 포함)에 대한 핸들러 함수, 그리고 마지막으로 항상 실행될 코드를 인자로 받는다.
아래는 `tryCatch` 함수의 사용 예시이다.
tryCatch({
  # 에러 발생 시뮬레이션
  stop("여기에 에러가 발생합니다")
  # 아래 코드는 위의 stop 함수 때문에 실행되지 않음
  cat("이 줄과 다음 줄은 에러가 먼저 잡히기 때문에 실행되지 않습니다\n")
  # 특정 클래스를 가진 에러 발생 (위의 stop으로 인해 이 부분은 실행되지 않음)
  stop( structure(simpleError("mySpecialError 메시지"), class=c("specialError", "error", "condition")) )
},
# 'specialError' 클래스의 에러를 처리하는 핸들러
specialError = function(e) {
  cat("specialError 클래스의 에러를 잡습니다\n")
},
# 일반적인 'error' 클래스의 에러를 처리하는 핸들러
error = function(e) {
  cat("기본 에러를 잡습니다\n")
  # 에러 객체 e의 내용을 출력할 수도 있음
  # print(e)
},
# 에러 발생 여부와 관계없이 항상 실행되는 부분
finally = {
  cat("일부 정리 작업을 수행합니다 (예: setwd)\n")
})
위 코드에서 `tryCatch`의 첫 번째 인자는 실행하려는 코드 블록이다. 이 블록 안에서 `stop` 함수가 호출되면 에러가 발생한다. `tryCatch`는 발생한 에러의 클래스(`class`)를 확인하고, 해당 클래스 이름과 일치하는 인자로 전달된 핸들러 함수를 찾아 실행한다. 예를 들어, 만약 `specialError` 클래스를 가진 에러가 발생했다면 `specialError = function(e){...}` 부분이 실행된다. 특정 클래스 핸들러가 없거나 매칭되지 않으면 일반적인 `error = function(e){...}` 핸들러가 실행된다. `finally` 인자로 전달된 코드 블록은 에러 발생 여부나 처리 여부와 관계없이 `tryCatch` 구문이 종료되기 전에 항상 실행된다. 이는 파일 연결을 닫거나 작업 디렉토리를 원래대로 복원하는 등의 정리 작업에 유용하게 사용될 수 있다.
2. 9. 22. [[Rebol]]
Rebol에서는 다양한 방법으로 예외와 오류를 처리할 수 있다.
`try` 블록을 사용하면 코드 실행 중 발생하는 오류를 포착할 수 있다. 오류가 발생하면 `error!` 타입의 객체가 반환된다. `error?` 함수로 오류 발생 여부를 확인하고, `disarm` 함수를 이용해 오류 객체의 세부 정보를 확인할 수 있다.
; try 블록을 사용하여 오류를 캡처하고 error! 객체로 변환
if error? exception: try [1 / 0] [
    probe disarm exception ; 오류 객체 정보 출력
]
`attempt`는 코드 블록을 실행하고, 오류가 발생하면 특별한 값인 `none`을 반환한다. 오류 없이 정상적으로 실행되면 해당 블록의 결과값을 반환한다.
; attempt는 블록 실행 결과 또는 오류 발생 시 none을 반환
print attempt [divide 1 0] ; 1 나누기 0은 오류이므로 none 출력
사용자가 직접 예외를 생성하여 던질 수도 있다. `throw` 명령어를 사용하면 문자열을 포함한 모든 데이터 타입을 예외로 사용할 수 있다. 이렇게 던져진 예외는 `catch` 블록을 사용하여 처리한다.
example: func ["예외를 발생시키는 함수"] [
    throw "이것은 문자열 예외입니다!"
]
; catch 블록으로 던져진 예외를 잡음
result: catch [example]
print ["잡힌 예외:" result]
`throw/name`을 사용하면 예외에 특정 이름을 부여할 수 있다. 이때 `make error!`를 사용하여 좀 더 구조화된 오류 객체를 생성하고 추가 정보를 담을 수도 있다. 이름이 지정된 예외는 `catch/name`을 사용하여 해당 이름을 가진 예외만 선택적으로 포착하여 처리할 수 있다.
sophisticated: func ["명명된 오류 예외를 발생시키는 함수"] [
    throw/name make error! "이것은 명명된 오류 예외입니다!" 'my-error-name
]
; 'my-error-name'이라는 이름의 예외만 잡음
result: catch/name [sophisticated] 'my-error-name
print ["잡힌 명명된 예외:" result]
2. 9. 23. [[Rexx]]
Rexx에서는 `signal on` 구문을 사용하여 특정 조건이나 예외 상황 발생 시 프로그램 흐름을 제어할 수 있다. 아래는 `signal on halt`를 이용해 사용자가 프로그램을 중단시키는 경우를 처리하는 예시 코드이다.
signal on halt; /* 'halt' 시그널 발생 시 'halt:' 레이블로 이동하도록 설정한다. */
do a = 1 /* 1부터 시작하는 무한 루프를 실행한다. */
say a /* 현재 변수 a의 값을 출력한다. */
do 100000 /* 의도적인 지연을 위한 내부 루프 */
end
end
halt: /* 'halt' 시그널 발생 시 프로그램 실행 흐름이 이곳으로 점프한다. */
say "프로그램이 사용자에 의해 중단되었습니다" /* 사용자에게 중단 메시지를 보여준다. */
exit /* 프로그램을 종료한다. */
위 코드에서 `signal on halt;` 구문은 프로그램 실행 중 `halt` 시그널(일반적으로 사용자의 인터럽트 요청)이 감지되면, 실행 위치를 즉시 `halt:` 레이블로 옮기도록 지시한다. `halt:` 레이블 다음에는 해당 시그널 발생 시 수행할 작업(여기서는 중단 메시지 출력 및 프로그램 종료)이 정의된다. 이를 통해 Rexx는 예외적인 프로그램 종료 상황에 대응하는 로직을 구현한다.
2. 9. 24. [[S-Lang]]
S-Lang에서는 다음과 같은 `try-catch-finally` 구문을 사용하여 예외를 처리한다.
try
{
% 예외를 발생시킬 수 있는 코드
}
catch SomeError:
{
% 이 예외를 처리하는 코드
}
catch SomeOtherError:
{
% 이 예외를 처리하는 코드
}
finally   % 선택적 블록
{
% 이 코드는 항상 실행됩니다.
}
`new_exception` 함수를 사용하여 새로운 예외를 생성할 수 있다. 예를 들어, 다음 코드는 `IOError`의 하위 클래스로 `MyIOError`라는 예외를 생성한다.
new_exception ("MyIOError", IOError, "My I/O Error");
`throw` 문을 사용하여 임의의 S-Lang 객체를 예외로 던질 수 있다.
2. 9. 25. [[Smalltalk]]
[ "예외를 발생시킬 수 있는 코드" ]
on: ExceptionClass
do: [:ex | "예외를 처리하는 코드" ].
스몰토크에서 예외 처리의 일반적인 메커니즘은 `'on:do:'` 메시지를 통해 제공된다.[6] 예외는 단순히 `'Error'` 클래스의 하위 클래스인 일반 객체이다. 인스턴스를 생성하고 `'#signal'` 메시지를 보내 예외를 발생시킨다. 예를 들어 `'MyException new signal'`과 같이 사용한다. 예외 처리 메커니즘인 `'#on:do:'` 역시 `'BlockClosure'`에 의해 구현된 일반적인 메시지이다. 발생한 예외는 처리 블록 클로저에 매개변수로 전달되며, 이 예외 객체를 확인하거나 필요에 따라 `'#resume'` 메시지를 보내 실행 흐름을 계속 진행시킬 수도 있다.
2. 9. 26. [[Tcl]]
Tcl에서는 `catch` 명령어를 사용하여 예외를 처리할 수 있다. `catch` 명령어는 스크립트를 실행하고, 오류가 발생하면 오류 메시지를 변수에 저장하며 0이 아닌 값을 반환한다.
if { [ catch {
    # 오류가 발생할 수 있는 코드
    foo
} err ] } {
    # 오류 발생 시 처리
    puts "오류 발생: $err"
}
Tcl 8.6 버전부터는 `try` 명령어도 사용할 수 있다. `try` 명령어는 더 구조화된 방식으로 예외를 처리할 수 있게 해주며, 특정 유형의 오류를 구분하여 처리하거나 정상 실행, 오류 발생 여부와 관계없이 항상 실행되어야 하는 코드를 `finally` 블록에 지정할 수 있다.
try {
    # 예외가 발생할 수 있는 명령어 실행
    someCommandWithExceptions
} on ok {res opt} {
    # 정상적으로 실행 완료 시 처리할 내용. 결과는 res 변수에, 옵션은 opt 딕셔너리에 저장됨.
} trap {ARITH DIVZERO} {err opt} {
    # ARITH DIVZERO 에러코드(0으로 나누기 오류)를 가진 예외 처리
} trap {POSIX ENOENT} {err opt} {
    # POSIX ENOENT 에러코드(파일 또는 디렉토리 없음)를 가진 예외 처리
    # ... 다른 특정 오류 패턴 처리 ...
} on error {err opt} {
    # 위에서 지정한 패턴 외의 모든 오류 처리. 오류 메시지는 err 변수에, 옵션은 opt 딕셔너리에 저장됨.
} finally {
    # try 블록 실행 후 성공/실패 여부와 관계없이 항상 실행되어야 하는 코드
    # 예를 들어 파일 닫기, 임시 자원 해제 등
}
2. 9. 27. [[VBScript]]
With New Try: On Error Resume Next
'do Something (단일 구문 권장)
.Catch: On Error GoTo 0: Select Case .Number
Case 0 ' 'Case Else' 절을 사용할 때 VBScript Case 문에 "Is" 키워드가 없기 때문에 이 줄이 필요합니다.
'예외 없음
Case SOME_ERRORNUMBER
'예외 처리
Case Else
'알 수 없는 예외
End Select: End With
' * Try 클래스 *
Class Try
Private mstrDescription
Private mlngHelpContext
Private mstrHelpFile
Private mlngNumber
Private mstrSource
Public Sub Catch()
mstrDescription = Err.Description
mlngHelpContext = Err.HelpContext
mstrHelpFile = Err.HelpFile
mlngNumber = Err.Number
mstrSource = Err.Source
End Sub
Public Property Get Source()
Source = mstrSource
End Property
Public Property Get Number()
Number = mlngNumber
End Property
Public Property Get HelpFile()
HelpFile = mstrHelpFile
End Property
Public Property Get HelpContext()
HelpContext = mlngHelpContext
End Property
Public Property Get Description()
Description = mstrDescription
End Property
End Class
2. 9. 28. [[Visual Basic 6]]
Visual Basic 6의 예외 처리 구문은 Basic과 매우 유사하며, 오류 처리는 각 프로시저 내에서 지역적으로 이루어진다.
' 오류 처리 활성화 및 핸들러 지정
On Error GoTo HandlerLabel ' 오류 발생 시 현재 프로시저 내의 HandlerLabel로 이동한다.
' 오류 처리 비활성화 (주석 처리됨)
' On Error GoTo 0 ' 오류 처리를 끈다. 이후 발생하는 오류는 치명적인 런타임 오류를 일으켜 애플리케이션을 중지시킨다.
' 다음 줄 계속 실행 (주석 처리됨)
' On Error Resume Next ' 오류가 발생해도 실행을 중단하지 않고 다음 명령으로 넘어간다. Err 객체에 오류 정보가 기록되므로 이를 확인하여 처리할 수 있다.
'... 코드 실행 ...
' 오류 발생시키기
Err.Raise 6 ' 내장 객체인 Err을 사용하여 "Overflow" 오류(오류 번호 6)를 발생시킨다.
            ' 만약 현재 프로시저에 오류 처리기가 없다면, 이 프로시저를 호출한 상위 프로시저에서 오류를 처리할 기회를 갖는다.
'... 코드 실행 ...
' 종료 전 정리 코드 (Finally 블록 유사 구현)
FinallyLabel: ' 프로시저 내 일반 레이블. 다른 언어의 Finally 구문과 유사한 역할을 하도록 비공식적으로 사용될 수 있다.
' 정리 코드 (오류 발생 여부와 관계없이 항상 실행되도록 구성)
Exit Sub ' 프로시저 정상 종료
' 오류 처리 핸들러 (오류 발생 시에만 실행됨)
' Exit Sub 문 뒤에 위치하여 일반적인 실행 흐름에서는 도달하지 않는다.
HandlerLabel: ' 오류 처리 코드 블록의 시작을 나타내는 레이블.
If Err.Number = 6 Then ' 발생한 오류 번호 확인 (Select Case 문이 여러 오류를 처리하기에 더 적합하다).
    ' 오류 처리 후 실행 흐름 제어
    Resume FinallyLabel ' 특정 레이블(FinallyLabel)로 이동하여 실행을 계속한다. (정리 코드 실행 목적)
    ' 또는 (주석 처리됨)
    ' Resume Next ' 오류가 발생한 문장의 *다음* 문장부터 실행을 계속한다.
    ' 또는 (주석 처리됨)
    ' Resume ' 오류가 발생한 *바로 그* 문장을 다시 실행한다. (무한 루프 주의)
End If
' 오류 정보 표시
MsgBox Err.Number & " " & Err.Source & " " & Erl & " " & Err.Description & " " & Err.LastDllError
' Err 객체의 주요 속성:
' Number: 오류 번호
' Source: 오류를 발생시킨 객체나 애플리케이션 이름
' Erl: 오류가 발생한 줄 번호 (VB6 내장 전역 변수, 사용 시 IDE 부가 기능 등으로 줄 번호가 매겨져 있어야 함)
' Description: 오류에 대한 설명 문자열
' LastDllError: 외부 DLL 호출 시 발생한 시스템 오류 코드
Resume FinallyLabel ' 처리 후 정리 코드로 이동
또한, 아래는 `Try` 클래스 객체를 사용하여 예외 처리를 구현하는 비공식적인 예시이다. 이는 Visual Basic .NET 이후의 `Try...Catch...Finally` 구문과 유사한 구조를 흉내 낸 것이다.
' Try 객체를 이용한 예외 처리 시도
With New Try ' Try 클래스의 새 인스턴스를 생성하고 사용한다.
    On Error Resume Next ' 오류 발생 시 다음 줄로 진행하도록 설정한다.
    ' 예외 발생 가능성이 있는 코드 (간결하게 한 문장 정도를 권장)
    ' 예: SomeObject.DoSomething()
    .Catch ' Try 객체의 Catch 메서드를 호출하여 Err 객체의 정보를 내부 변수에 저장한다.
    On Error GoTo 0 ' Err 객체 정보를 저장했으므로, 기본 오류 처리(런타임 오류 발생)로 복구한다.
    Select Case .Number ' Try 객체에 저장된 오류 번호(.Number 속성)를 확인한다.
        Case SOME_ERRORNUMBER ' 특정 오류 번호에 대한 처리
            ' 해당 예외 처리 코드
        Case Is <> 0 ' 0이 아닌 다른 모든 오류 번호 (즉, 어떤 오류든 발생한 경우)
            ' 알 수 없는 예외 처리 코드
        Case Else ' 오류 번호가 0인 경우 (오류가 발생하지 않음)
            ' 정상 처리 코드 (필요한 경우)
    End Select
End With ' Try 객체 사용 종료
' * Try 클래스 정의 *
Private mstrDescription As String
Private mlngHelpContext As Long
Private mstrHelpFile As String
Private mlngLastDllError As Long
Private mlngNumber As Long
Private mstrSource As String
' Err 객체의 정보를 클래스 내부 변수에 저장하는 메서드
Public Sub Catch()
    mstrDescription = Err.Description
    mlngHelpContext = Err.HelpContext
    mstrHelpFile = Err.HelpFile
    mlngLastDllError = Err.LastDllError
    mlngNumber = Err.Number
    mstrSource = Err.Source
End Sub
' 저장된 오류 정보를 읽기 위한 속성들
Public Property Get Source() As String
    Source = mstrSource
End Property
Public Property Get Number() As Long
    Number = mlngNumber
End Property
Public Property Get LastDllError() As Long
    LastDllError = mlngLastDllError
End Property
Public Property Get HelpFile() As String
    HelpFile = mstrHelpFile
End Property
Public Property Get HelpContext() As Long
    HelpContext = mlngHelpContext
End Property
Public Property Get Description() As String
    Description = mstrDescription
End Property
2. 9. 29. [[Visual Basic .NET]]
Visual Basic .NET에서 예외 처리는 Try...Catch...Finally 문을 사용하여 수행된다. Try 블록은 반드시 하나 이상의 Catch 절 또는 하나의 Finally 절을 포함해야 하며, Finally 절은 최대 하나만 가질 수 있다.
Try
    ' 예외가 발생할 수 있는 코드를 여기에 작성한다.
Catch ex As Exception When 조건
    ' 특정 조건이 참일 때 예외를 처리한다. 예외 객체는 "ex" 변수에 저장된다.
Catch ex As ExceptionType
    ' 지정된 형식의 예외(예: DivideByZeroException, OverflowException 등)를 처리한다.
Catch ex As Exception
    ' 이전에 지정되지 않은 다른 모든 형식의 예외를 처리한다.
Catch
    ' 비 CLR 예외를 포함하여 발생 가능한 모든 예외를 처리한다.
Finally
    ' 이 코드는 Try 블록(및 Catch 절) 실행이 끝날 때 항상 실행된다.
    ' 예외 발생 여부나 처리 여부와 관계없이 실행되므로,
    ' 파일 핸들러와 같은 리소스를 정리하고 닫는 데 주로 사용된다.
    ' 단, Environment.FailFast() 호출, 전원 손실과 같은 시스템 전체의 예외적 상황,
    ' 또는 다른 스레드의 예외로 인해 프로세스가 중단되는 경우에는 실행되지 않을 수 있다.
End Try
2. 9. 30. [[Visual Prolog]]
wikitext
try
% 보호할 블록
catch TraceId do
% 예외 발생 시 실행할 코드; TraceId는 예외 정보에 접근할 수 있게 해줍니다.
finally
% 다른 부분의 동작과는 관계없이 실행될 코드
end try
2. 9. 31. [[X++]]
X++는 마이크로소프트 다이나믹스 AX 환경에서 사용되는 객체 지향 프로그래밍 언어이다. X++에서는 `try` 블록과 `catch` 블록을 사용하여 예외 처리를 수행한다.
다음은 X++의 기본적인 예외 처리 구문 예시이다.
public static void main(Args _args)
{
    try
    {
        // 예외를 발생시킬 수 있는 코드
    }
    catch (Exception::Error) // 또는 다른 예외 유형
    {
        // 오류 처리
    }
    catch
    {
        // 이전에 처리되지 않은 다른 모든 예외 유형 처리
    }
    // 여기에 있는 코드는 예외가 포착되는 한 실행됩니다.
}
참조
[1] 
웹사이트
 
Bjarne Stroustrup's FAQ
 
http://www.stroustru[...] 
[2] 
웹사이트
 
Handling exceptions
 
https://web.archive.[...] 
2014-01-01
 
[3] 
웹사이트
 
Exception handling tags
 
https://web.archive.[...] 
2014-01-01
 
[4] 
웹사이트
 
JBoss Community issue tracker ticket for adding retry
 
https://issues.jboss[...] 
[5] 
서적
 
Delphi Version 7.0, Online help
 
Borland
 
[6] 
웹사이트
 
Pharo by Example
 
https://web.archive.[...] 
2010-03-20
 
[7] 
웹사이트
 
Try-Catch for VB
 
https://web.archive.[...] 
2012-03-17
 
[8] 
웹사이트
 
Language_Reference/Terms#Try-catch-finally
 
http://wiki.visual-p[...] 
                        
                        본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다. 
                        모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
                        하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다. 
                        따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
                        
                        문의하기 : help@durumis.com