티스토리 뷰

Back-end/Ruby on Rails

[루비] 예외 처리

jhkang-dev 2019. 2. 13. 09:53

예외처리



예외 처리하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'open-uri'
page = 'podcasts'
file_name = "#{page}.html"
web_page = open("http://pragprog.com/#{page}")
output = File.open(file_name, 'w')
begin
  while line = web_page.gets
    output.puts line
  end
output.close
rescue Exception
  STDERR.puts "Failed to download #{page}: #{$!}"
  output.close
  File.delete(file_name)
  raise
end
cs

예외가 발생하면 루비는 이후의 예외 처리 과정과 별도로 관련된 예외 객체 참조 전역변수 $!에 담는다.

파일을 닫고 지운 뒤, raise를 매개변수 없이 호출해서 $!에 담긴 예외를 다시 발생시킨다. raise는 예외를 거르거나, 다룰 수 없는 예외를 더 높은 계층으로 넘기는 유용한 기법이다.


각 rescue 절의 끝에는 예외 객체를 받을 지역변수 이름을 쓸 수 있다.

1
2
3
4
5
6
7
begin
  eval string
rescue SyntaxError, NameError => boom
  print "String doesn't compile: " + boom
rescue StandardError => bang
  print "Error running script: " + bang
end
cs



루비가 rescue 절을 실행하는 방법

1) 발생된 예외와 rescue의 매개 변수를 비교한다. 매개 변수에 해당한다면 그 rescue 문을 실행하고 탐색을 멈춘다

2) rescue 절을 아무런 매개변수 없이 쓴다면, 매개변수의 기본값은 StandardError가 된다.

3) 적절한 rescue 구문을 찾을 수 없거나, 예외가 begin/end 블록 바깥에서 발생한 경우에는 스택을 거슬러 올라가서 호출자에서 예외 처리 구문을 찾는다. 호출자에도 없으면 호출자의 호출자를 찾는 식으로 계속 예외 처리를 찾아간다.


Ensure 예외 처리시 반드시 실행해야 하는 구문

예외가 발생했건 아지 않았건 코드 블록의 끝부분에 특정 작업을 반드시 실행해야 하는 경우에 ensure를 사용한다. Java의 final과 동일한 역할을 한다.

ensure는 rescue 절 뒤에 오는데, 블록이 끝날 때 반드시 실행되어야 하는 코드를 여기에 적어준다.

1
2
3
4
5
6
7
8
9
= file.open("testfile")
begin
  #.. 프로세스
rescue
  #.. 에러처리
ensure
  f.close
end
 
cs


초심자들이 흔히 FIle.open을 begin 절 안에 넣는 실수를 저지른다. 이 경우 open 자체가 예외를 발생시킬 수 있기 때문에 애초에 ensure문에서 close할 필요가 없어지는 것이다.







댓글