Exception 클래스

Exception 클래스 (Exception)

Exception 클래스와 그 서브클래스들은 Kernel#raisebegin ... end 블록 안의 rescue 문 사이에서 정보를 주고받는 데 사용돼요.

Exception 객체는 예외에 관한 정보를 담고 있어요.

  • 예외의 타입(예외의 클래스)
  • 선택적인 설명 메시지(message)
  • 선택적인 백트레이스(backtrace) 정보

Exception의 내장 서브클래스 중에는 추가 메서드를 가진 것도 있어요. 예를 들어 NameError#name 같은 게 있죠.

출처: Ruby 3.3 API

본문

기본값 (Defaults)

두 Ruby 문장에는 기본 예외 클래스가 있어요.

  • raise: 기본은 RuntimeError예요.
  • rescue: 기본은 StandardError예요.

전역 변수 (Global Variables)

예외가 발생했지만 아직 처리되지 않았을 때(rescue, ensure, at_exit, END 블록 안에서), 두 개의 전역 변수가 설정돼요.

  • $! — 현재 예외를 담아요.
  • $@ — 그 백트레이스를 담아요.

사용자 정의 예외 (Custom Exceptions)

추가 정보나 대안 정보를 제공하기 위해 프로그램은 내장 예외 클래스에서 파생된 사용자 정의 예외 클래스를 만들 수 있어요.

좋은 관행은 라이브러리가 하나의 "일반적인"(generic) 예외 클래스(보통 StandardErrorRuntimeError의 서브클래스)를 만들고, 다른 예외 클래스들이 그 클래스에서 파생되게 하는 것이에요. 그러면 사용자가 그 일반 예외를 rescue해서, 라이브러리가 앞으로 새 예외 서브클래스를 추가해도 그 라이브러리가 발생시킬 수 있는 모든 예외를 잡을 수 있어요.

class MyLibrary
  class Error < ::StandardError
  end

  class WidgetError < Error
  end

  class FrobError < Error
  end

end

MyLibrary::WidgetErrorMyLibrary::FrobError를 모두 처리하려면, 라이브러리 사용자는 MyLibrary::Errorrescue하면 돼요.

내장 예외 클래스 (Built-In Exception Classes)

Exception의 내장 서브클래스는 다음과 같아요.

NoMemoryError
ScriptError
  LoadError
  NotImplementedError
  SyntaxError
SecurityError
SignalException
  Interrupt
StandardError
  ArgumentError
  UncaughtThrowError
  EncodingError
  FiberError
  IOError
    EOFError
  IndexError
    KeyError
    StopIteration
    ClosedQueueError
  LocalJumpError
  NameError
    NoMethodError
  RangeError
    FloatDomainError
  RegexpError
  RuntimeError
    FrozenError
  SystemCallError
    Errno::*
  ThreadError
  TypeError
  ZeroDivisionError
SystemExit
SystemStackError
fatal

::exception (Public Class Method)

exception([string]) → an_exception 또는 exc — 인자가 없거나 인자가 receiver와 같으면 receiver를 돌려줘요. 그 외에는 receiver와 같은 클래스이지만 메시지가 string.to_str과 같은 새 예외 객체를 만들어요.

::json_create (Public Class Method)

json_create(object)as_json 참고. 예외 객체를 역직렬화해요.

# File ext/json/lib/json/add/exception.rb, line 9
def self.json_create(object)
  result = new(object['m'])
  result.set_backtrace object['b']
  result
end

::new (Public Class Method)

new(msg = nil) → exception (별칭 exception(msg = nil)) — 선택적으로 메시지를 전달하며 새 Exception 객체를 만들어요.

::to_tty? (Public Class Method)

to_tty?true 또는 false — 예외 메시지가 tty로 보내질 것이면 true를 돌려줘요.

#== (Public Instance Method)

exc == objtrue 또는 false — 동등성. objException이 아니면 false. 그 외에는 excobj가 같은 클래스, 메시지, 그리고 백트레이스를 공유하면 true를 돌려줘요.

#as_json (Public Instance Method)

as_json(*)Exception#as_jsonException.json_create 메서드를 사용해 Exception 객체를 직렬화·역직렬화할 수 있어요(Marshal 참고). as_jsonself를 직렬화해서 2-요소 해시로 돌려줘요.

require 'json/add/exception'
x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil}

JSON.create는 그런 해시를 역직렬화해서 Exception 객체로 돌려줘요.

Exception.json_create(x) # => #<Exception: Foo>
# File ext/json/lib/json/add/exception.rb, line 29
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'm'            => message,
    'b'            => backtrace,
  }
end

#backtrace (Public Instance Method)

backtrace → array 또는 nil — 예외와 연관된 백트레이스를 돌려줘요. 백트레이스는 문자열의 배열인데, 각각 "filename:lineNo: in 'method'" 또는 "filename:lineNo" 형태예요.

def a
  raise "boom"
end

def b
  a()
end

begin
  b()
rescue => detail
  print detail.backtrace.join("\n")
end

이 코드는 이렇게 출력해요.

prog.rb:2:in `a'
prog.rb:6:in `b'
prog.rb:10

백트레이스가 설정되지 않은 경우에는 nil을 돌려줘요.

ex = StandardError.new
ex.backtrace
#=> nil

#backtrace_locations (Public Instance Method)

backtrace_locations → array 또는 nil — 예외와 연관된 백트레이스를 돌려줘요. Exception#backtrace와 비슷하지만 Thread::Backtrace::Location의 배열이에요. 이 메서드는 Exception#set_backtrace()의 영향을 받지 않아요.

#cause (Public Instance Method)

cause → an_exception 또는 nil — 이 예외가 발생한 시점의 이전 예외($!)를 돌려줘요. 예외를 감싸고 원래 예외 정보를 유지할 때 유용해요.

#detailed_message (Public Instance Method)

detailed_message(highlight: bool, **opt) → string — message가 돌려준 문자열을 처리해요. 첫 줄 끝에 예외 클래스의 이름을 추가할 수 있고, highlight 키워드가 true이면 메시지를 굵게 만들기 위한 ANSI 이스케이프 시퀀스를 추가해요.

이 메서드를 오버라이드할 때는 알 수 없는 키워드 인자에 관대해야 해요. full_message에 전달되는 모든 키워드 인자는 이 메서드로 위임돼요. did_you_meanerror_highlight가 이 메서드를 오버라이드해서 자기 정보를 추가해요.

사용자 정의 예외 클래스도 자신만의 detailed_message 메서드를 정의해 보충 정보를 추가할 수 있어요. highlighttrue일 때는 이스케이프 시퀀스를 포함한 문자열을 돌려줄 수 있지만, 널리 지원되는 것만 써야 해요. 다음 코드로 제한하는 게 좋아요.

Reset (\e[0m)
Bold (\e[1m)
Underline (\e[4m)
Foreground color except white and black
  Red (\e[31m)
  Green (\e[32m)
  Yellow (\e[33m)
  Blue (\e[34m)
  Magenta (\e[35m)
  Cyan (\e[36m)

highlighttrue여도 이스케이프 시퀀스를 신중히 사용하세요. 필수 정보를 전달하는 데 이스케이프 시퀀스를 쓰지 마세요. 모든 이스케이프 시퀀스를 무시해도 메시지를 읽을 수 있어야 해요.

#exception (Public Instance Method)

exception([string]) → an_exception 또는 exc — 인자가 없거나 receiver와 같으면 receiver를 돌려줘요. 그 외에는 receiver와 같은 클래스이지만 메시지가 string.to_str과 같은 새 예외 객체를 만들어요.

#full_message (Public Instance Method)

full_message(highlight: bool, order: [:top or :bottom]) → string — 예외의 서식이 지정된 문자열을 돌려줘요. Ruby가 처리되지 않은 예외를 stderr로 출력할 때 쓰는 것과 같은 형식을 사용해요. highlighttrue이면 기본 에러 핸들러가 메시지를 tty로 보내요. order:top 또는 :bottom이어야 하고, 에러 메시지와 가장 안쪽 백트레이스를 위/아래 중 어디에 놓을지 정해요. 이 옵션들의 기본값은 호출 시점의 $stderr와 그 tty?에 따라 달라져요.

#inspect

inspect → string — 이 예외의 클래스 이름과 메시지를 돌려줘요.

#message

message → string — exception.to_s를 호출한 결과를 돌려줘요. 보통 예외의 메시지나 이름을 돌려줘요.

#set_backtrace (Public Instance Method)

set_backtrace(backtrace) → array — exc와 연관된 백트레이스 정보를 설정해요. 백트레이스는 Exception#backtrace에 설명된 형식의 String 객체 배열 또는 단일 String이어야 해요.

#to_json

to_json(*args)self를 나타내는 JSON 문자열을 돌려줘요.

require 'json/add/exception'
puts Exception.new('Foo').to_json

출력:

{"json_class":"Exception","m":"Foo","b":null}
# File ext/json/lib/json/add/exception.rb, line 46
def to_json(*args)
  as_json.to_json(*args)
end

#to_s

to_s → string — 예외의 메시지를 돌려줘요(메시지가 설정되지 않았으면 예외의 이름을 돌려줘요).