Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby에서 예외 구조하기

발생한 예외는 일단 호출 스택의 맨 위에 도달하면 애플리케이션이 충돌하는 것을 방지하기 위해 구출될 수 있습니다. 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로 알려주십시오. 물론 이 기사가 어떻게 마음에 들었는지, 또는 더 알고 싶은 다른 주제가 있는지 알고 싶습니다.