발생한 예외는 일단 호출 스택의 맨 위에 도달하면 애플리케이션이 충돌하는 것을 방지하기 위해 구출될 수 있습니다. Ruby에서는 rescue
를 사용합니다. 키워드입니다.
Ruby에서 예외를 복구할 때 복구해야 하는 특정 오류 클래스를 지정할 수 있습니다.
begin
raise 'This exception will be rescued!'
rescue StandardError => e
puts "Rescued: #{e.inspect}"
end
참고 :raise
사용 시 예외 클래스를 지정하지 않으면 Ruby는 기본적으로 RuntimeError
가 됩니다. .
구조할 단일 예외 클래스를 지정하는 것 외에도 rescue
에 예외 클래스 배열을 전달할 수 있습니다. 예어. 이렇게 하면 여러 오류에 동일한 방식으로 응답할 수 있습니다.
begin
raise 'This exception will be rescued!'
rescue StandardError, AnotherError => e
puts "Rescued: #{e.inspect}"
end
다중 rescue
블록은 다른 방식으로 다른 오류를 처리하는 데 사용할 수 있습니다. 이는 다양한 시나리오에 대해 서로 다른 예외를 생성하는 라이브러리로 작업할 때 유용할 수 있습니다.
begin
raise 'This exception will be rescued!'
rescue StandardError => e
puts "Rescued: #{e.inspect}"
rescue AnotherError => e
puts "Rescued, but with a different block: #{e.inspect}"
end
예외 계층
Ruby의 예외 계층 구조는 여러 유형의 오류를 구별하는 데 사용되는 동시에 모든 오류를 지정하지 않고도 오류 그룹에서 구조할 수 있는 기능을 제공합니다.
라이브러리가 자체 예외 하위 클래스를 정의할 수 있지만 Ruby 2.5의 기본 제공 예외 하위 클래스 목록은 다음과 같습니다.
- NoMemoryError
- ScriptError
- LoadError
- NotImplementedError
- SyntaxError
- SecurityError
- SignalException
- Interrupt
- StandardError (default for `rescue`)
- ArgumentError
- UncaughtThrowError
- EncodingError
- FiberError
- IOError
- EOFError
- IndexError
- KeyError
- StopIteration
- LocalJumpError
- NameError
- NoMethodError
- RangeError
- FloatDomainError
- RegexpError
- RuntimeError (default for `raise`)
- SystemCallError
- Errno::*
- ThreadError
- TypeError
- ZeroDivisionError
- SystemExit
- SystemStackError
- fatal (impossible to rescue)
rescue
에서 예외 클래스를 생략할 때 블록, StandardError
가정됩니다. ArgumentError
때문에 및 NoMethodError
StandardError
의 하위 클래스입니다. , 이들은 블록에서 발생했을 때 구출됩니다.
예외 계층이 작동하는 방식의 좋은 예는 SystemCallError
입니다. , 저수준 플랫폼 종속 예외 클래스입니다. 파일을 읽거나 쓸 때 가장 많이 나타납니다.
Ruby의 File.read
메서드는 파일 읽기에 실패하면 예외를 발생시킵니다. 이는 파일이 존재하지 않거나 프로그램이 파일을 읽을 수 있는 올바른 권한이 없는 것과 같은 여러 가지 이유로 인해 발생할 수 있습니다.
이러한 문제는 플랫폼에 따라 다르므로 Ruby는 시스템에서 실행 중인 운영 체제의 종류에 따라 다른 예외를 발생시킬 수 있습니다. 이와 같은 저수준 오류의 경우 Ruby는 다른 Errno::*
목록을 구현합니다. - 플랫폼별 예외
이 모든 Errno::*
예외는 SystemCallError
의 하위 클래스입니다. . 플랫폼에 따라 다르지만 rescue
에서 계속 사용할 수 있습니다. SystemCallError
에서 구출하여 차단 .
begin
File.read("does/not/exist")
rescue SystemCallError => e
puts "Rescued: #{e.inspect}"
end
삼키는 예외
일반적으로 예외를 구할 때는 의도하지 않게 예외를 삼키는 것을 방지하기 위해 가능한 한 구체적으로 작성하는 것이 가장 좋습니다.
image = nil
begin
File.read(image.filename)
rescue
puts "File can't be read!"
end
이 예에서 image
변수는 nil
입니다. , 그래서 NoMethodError
를 발생시킵니다. #filename
을 호출하려고 할 때 그것에 (NoMethodError: undefined method `filename' for nil:NilClass
). 모든 StandardError
때문에 하위 클래스는 (NoMethodError
포함)에서 구출됩니다. ), 예외를 삼키고 "파일을 읽을 수 없습니다!"라는 메시지가 출력됩니다. 이렇게 하면 코드에서 가능한 버그가 숨겨집니다.
참고 :가능하지만 Exception
사용 rescue
의 슈퍼클래스 차단은 매우 권장되지 않습니다.
Ruby에서 예외를 발생시키거나 복구하는 방법에 대해 질문이 있습니까? 주저하지 말고 @AppSignal로 알려주십시오. 물론 이 기사가 어떻게 마음에 들었는지, 또는 더 알고 싶은 다른 주제가 있는지 알고 싶습니다.