Ruby Language                
            예외
        
        
            
    수색…
비고
예외 는 예외 조건의 발생을 나타내는 오브젝트입니다. 다른 말로하면, 뭔가 잘못되었다는 뜻입니다.
 Ruby에서 예외 는 종종 오류 라고 합니다 . 이는 기본 Exception 클래스가 최상위 예외 객체 요소로 존재하지만 사용자 정의 실행 예외가 일반적으로 StandardError 또는 하위 항목이기 때문입니다. 
예외 발생
 예외를 발생 시키려면 Kernel#raise 가 예외 클래스 및 / 또는 메시지를 전달합니다. 
raise StandardError # raises a StandardError.new
raise StandardError, "An error" # raises a StandardError.new("An error")
 오류 메시지를 전달하기 만하면됩니다. 이 경우 메시지는 RuntimeError 로 래핑됩니다. 
raise "An error" # raises a RuntimeError.new("An error")
다음은 그 예입니다.
def hello(subject)
  raise ArgumentError, "`subject` is missing" if subject.to_s.empty?
  puts "Hello #{subject}"
end
hello # => ArgumentError: `subject` is missing
hello("Simone") # => "Hello Simone"
사용자 정의 예외 유형 작성
 사용자 정의 예외가 확장하는 모든 클래스 Exception 또는 서브 클래스 Exception . 
 일반적으로 StandardError 또는 하위 클래스는 항상 확장해야합니다. Exception 패밀리는 일반적으로 가상 시스템 또는 시스템 오류를위한 것이므로이를 복구하면 예상대로 강제 중단이 수행되지 않을 수 있습니다. 
# Defines a new custom exception called FileNotFound
class FileNotFound < StandardError
end
def read_file(path)
  File.exist?(path) || raise(FileNotFound, "File #{path} not found")
  File.read(path)
end
read_file("missing.txt")  #=> raises FileNotFound.new("File `missing.txt` not found")
read_file("valid.txt")    #=> reads and returns the content of the file
 끝에 Error 접미어를 추가하여 예외의 이름을 지정하는 것이 일반적입니다. 
-  ConnectionError
-  DontPanicError
 그러나 오류가 자체적으로 설명 할 수있는 경우 중복 될 수 있으므로 Error 접미사를 추가하지 않아도됩니다. 
-  FileNotFound대FileNotFoundError
-  DatabaseExploded대DatabaseExplodedError
예외 처리
 begin/rescue 블록을 사용하여 예외를 잡아 (구조) 처리하십시오. 
begin
  # an execution that may fail
rescue
  # something to execute in case of failure
end
 rescue 절은 C # 또는 Java와 같은 중괄호로 된 catch 블록과 유사합니다. 
 이처럼 벌거 벗은 rescue 는 StandardError 구출합니다. 
 참고 : 기본 StandardError 대신 Exception 을 catch하지 않도록주의하십시오. Exception 클래스에는 SystemExit 및 NoMemoryError 및 일반적으로 catch하지 않으려는 기타 심각한 예외가 포함됩니다. StandardError (기본값) 대신 항상 catch하는 것이 좋습니다. 
구조해야하는 예외 클래스를 지정할 수도 있습니다.
begin
  # an excecution that may fail
rescue CustomError
  # something to execute in case of CustomError
  # or descendant
end
 이 구조 절은 CustomError 가 아닌 예외를 catch하지 않습니다. 
특정 변수에 예외를 저장할 수도 있습니다.
begin
  # an excecution that may fail
rescue CustomError => error
  # error contains the exception
  puts error.message # provide human-readable details about what went wrong.
  puts error.backtrace.inspect # return an array of strings that represent the call stack
end
예외 처리에 실패한 경우 언제든지 구조 블록에서 예외를 발생시킬 수 있습니다.
begin
   #here goes your code
rescue => e
    #failed to handle 
    raise e
end
 begin 블록을 다시 시도하려면 retry를 호출 retry . 
begin
   #here goes your code
rescue StandardError => e
   #for some reason you want to retry you code
   retry
end
 다시 시도 할 때마다 예외가 발생하면 루프에 빠질 수 있습니다. 이를 방지하려면 retry_count 를 특정 시도 횟수로 제한하십시오. 
retry_count = 0
begin
      # an excecution that may fail
rescue
    if retry_count < 5
        retry_count = retry_count + 1
        retry
    else
        #retry limit exceeds, do something else
    end
 else 블록이나 ensure 블록을 제공 할 수도 있습니다. else 블록은 예외가 발생하지 않고 begin 블록이 완료 될 때 실행됩니다. ensure 블록이 항상 실행됩니다. ensure 블록은 C # 또는 Java와 같은 중괄호 언어로 된 finally 블록과 유사합니다. 
begin
  # an execution that may fail
rescue
  # something to execute in case of failure
else
  # something to execute in case of success
ensure
  # something to always execute
end
 def , module 또는 class 블록 안에 있다면 begin 문을 사용할 필요가 없습니다. 
def foo
    ...
rescue
    ...
end
여러 예외 처리
 동일한 rescue 선언에서 여러 오류를 처리 할 수 있습니다. 
begin
  # an execution that may fail
rescue FirstError, SecondError => e
  # do something if a FirstError or SecondError occurs
end
 다중 rescue 선언을 추가 할 수도 있습니다. 
begin
  # an execution that may fail
rescue FirstError => e
  # do something if a FirstError occurs
rescue SecondError => e
  # do something if a SecondError occurs
rescue => e
  # do something if a StandardError occurs
end
 rescue 블록의 순서는 중요합니다. 첫 번째 일치 항목은 실행 된 항목입니다. 따라서 StandardError 를 첫 번째 조건으로 설정하고 예외가 모두 StandardError 에서 상속되면 다른 rescue 문은 실행되지 않습니다. 
begin
  # an execution that may fail
rescue => e
  # this will swallow all the errors
rescue FirstError => e
  # do something if a FirstError occurs
rescue SecondError => e
  # do something if a SecondError occurs
end
 일부 블록은 def , class 및 module 과 같은 암시적인 예외 처리 기능을 가지고 있습니다. 이 블록을 사용하면 begin 문을 건너 뛸 수 있습니다. 
def foo
    ...
rescue CustomError
    ...
ensure
    ...
end
예외 (사용자 정의) 예외에 정보 추가
로깅을 목적으로 또는 예외가 포착 된 경우 조건부 처리를 허용하기 위해 예외가있는 추가 정보를 포함하는 것이 유용 할 수 있습니다.
class CustomError < StandardError
  attr_reader :safe_to_retry
  def initialize(safe_to_retry = false, message = 'Something went wrong')
    @safe_to_retry = safe_to_retry
    super(message)
  end
end
예외 발생시키기 :
raise CustomError.new(true)
예외 잡기 및 제공된 추가 정보 액세스 :
begin
  # do stuff
rescue CustomError => e
  retry if e.safe_to_retry
end