Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104668666
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Oracle

2008-05-22 17:39:15

   来源:

Ruby 异常处理

Ruby 具有一些可用于脚本和面向对象的应用程序的强大特性。其中一个特性是 Ruby 的异常处理。清单 12 包含使用 Ruby 的异常处理机制的示例。

清单12:rubyExceptions.rb

=begin

This script is similar to Listing 10, but demonstrates Ruby exception handling

using functionality originally demonstrated in Listing 10.

=end

fileName = ARGV.to_s

#obtain file name if not provided on command-line

if fileName.size < 1

print "Enter init.ora path and name: "

fileName = gets.chomp!

end

#ensure something has been provided for file name

begin

if fileName.size < 1

raise ArgumentError, "No valid file name provided" + "n"

end

rescue ArgumentError => argErr

print argErr

raise # re-raise this exception and force script termination

end

#get file contents

begin #Begin exception handling block for file I/O

theFile = File.new(fileName, "r")

text = theFile.read

theFile.close

rescue IOError

print "I/O Error: Problem accessing file " + fileName + "n"

exit

rescue Errno::ENOENT

print "ENOENT: Cannot find file " + fileName + "n"

exit

rescue Errno::EPERM

print "EPERM: Insufficient rights to open " + fileName + "n"

raise

rescue Exception # Catch-all: More exceptions captured than with "rescue" alone

print "Generic error rescued (captured) during file I/O attempt." + "n"

raise

else

print "Good news! There was no problem with file I/O for " + fileName + "n"

ensure

print "Good or bad, file handling attempt is now complete!n"

end #End exception handling block for file I/O

#obtain text string for regular expression

print "Enter regular expression pattern: "

pattern = gets.chomp!

begin #Begin exception handling block for regular expression

regExp = Regexp.new(pattern)

rescue RegexpError

print "Problem with regular expression " + regExp.to_s + "n"

exit # Nothing to be done with a bad regular expression

ensure

print "Regular expression evaluated was: " + regExp.to_s + "n"

end #End exception handling block for regular expression

puts text.scan(regExp)

清单 12 演示了使用 begin 关键字标记可以引发(抛出)异常的代码块的起始位置。该清单中使用关键字 raise 供脚本引发(抛出)自己的异常。关键字 rescue 多次出现,与 Java 的 catch 关键字类似。Ruby 的 ensure 关键字与 Java 的 finally 关键字类似,在该代码清单中用于执行功能,无论是否遇到异常。

如清单 12 所示,Ruby 还支持 else 关键字涵盖以下情况下应该执行的功能:如果未针对由 begin 和 end 指示的特定代码块抛出任何异常。代码清单的注释进一步解释了 Ruby 的异常处理功能。

图 11 显示了运行清单 12 中的脚本三次的结果。第一次运行该脚本时,故意提供了一个未知的文件名以调用文件处理异常处理。第二次运行该脚本时用正确的文件名演示 else 块的执行,并允许执行转至与正则表达式处理相关的代码块。第二次执行该脚本时,提供了一个错误的表达式以演示 RegexpError 的处理。第三次运行该脚本时演示了脚本的完整运行,不引发异常。所有这三次运行都演示了 ensure 块的执行,因为无论是否引发(抛出)异常,所有异常处理过程中始终调用该块。

图11:正在运行的 Ruby 异常

Ruby DBI 异常处理。 最后一部分介绍了 Ruby 异常处理。Ruby/DBI 提供了自己的异常处理层次结构,如清单 13 所示。实际上,较常见的是只捕获“database catch all”异常 DBI::DatabaseError 并访问清单 13 中所显示的属性,以打印出数据库错误代码和错误消息。

清单13:rubyDbExceptions.rb

=begin

Listing13-rubyDbExceptions.rb

This script demonstrates the use of exceptions with DBI::DatabaseError

and database-related exception classes that inherit from DBI::DatabaseError.

Often, it is enough to capture DatabaseError, but this example shows all

of the inherited exception classes. DatabaseError is rescued last so that

a more particular database-related exception might be rescued first.

This "try" block of this code includes an "infinite" while loop that will

open connections without closing them until a DBI::DatabaseError is forced.

=end

require 'dbi'

begin

counter = 0

while 0 # "infinite" loop because 0 resolves to "true" for Ruby conditional

dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')

counter += 1

puts "DB Connection #" + counter.to_s + "n"

#Intentionally NOT closing with dbh.close to force DatabaseError.

end

rescue DBI::DataError => dataErr

dbh.rollback

puts "DB error due to problem with data"

puts "Error Code: #{dataErr.err}"

puts "Error Message: #{dataErr.errstr}"

puts "DB rollback.n"

rescue DBI::IntegrityError => integErr

# Example: Trying to insert same value for unique column twice.

dbh.rollback

puts "DB error due to integrity problem."

puts "Error Code: #{integErr.err}"

puts "Error Message: #{integErr.errstr}"

puts "DB rollback.n"

rescue DBI::InternalError => internErr

dbh.rollback

puts "DB error database internal error."

puts "Error Code: #{internErr.err}"

puts "Error Message: #{internErr.errstr}"

puts "DB rollback.n"

rescue DBI::NotSupportedError => notSuppErr

dbh.rollback

puts "DB feature not supported."

puts "Error Code: #{notSuppErr.err}"

puts "Error Message: #{notSuppErr.errstr}"

puts "DB rollback.n"

rescue DBI::OperationalError => opErr

dbh.rollback

puts "DB error due to problems with operation of database."

puts "Error Code: #{opErr.err}"

puts "Error Message: #{opErr.errstr}"

puts "DB rollback.n"

rescue DBI::ProgrammingError => dbProgErr

# Example: Bad column name in SQL statement.

dbh.rollback

puts "DB error due to programming problem.n"

puts "Error Code: #{dbProgErr.err}"

puts "Error Message: #{dbProgErr.errstr}"

puts "DB rollback.n"

rescue DBI::DatabaseError => dbErr

# Catch-all for all database exceptions.

dbh.rollback

puts "Database exception encountered."

puts "Error Code: #{dbErr.err}"

puts "Error Message: #{dbErr.errstr}"

puts "DB rollback."

rescue DBI::InterfaceError => ifError

dbh.rollback

puts "Problem with DBI interface encountered."

rescue RuntimeError

dbh.rollback

puts "Unknown error (not DB or DBI) encountered."

else

puts "DB commit.n"

dbh.commit

ensure

puts "Disconnecting database handler."

dbh.disconnect

end

阅读(634) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~