Khóa học ruby

Xử lý Exceptions trong Ruby

0 phút đọc

Xử lý exceptions là một phần quan trọng trong lập trình Ruby, giúp bạn quản lý và xử lý các lỗi xảy ra trong quá trình thực thi chương trình. Ruby cung cấp một cơ chế mạnh mẽ để xử lý exceptions, cho phép bạn viết mã an toàn và đáng tin cậy hơn. Trong bài viết này, chúng ta sẽ tìm hiểu chi tiết về cách xử lý exceptions trong Ruby, bao gồm cú pháp, cách sử dụng các câu lệnh retry, raise, ensure, else, catchthrow, cũng như lớp Exception.

Cú pháp (Syntax)

Cú pháp cơ bản để xử lý exceptions trong Ruby là sử dụng khối begin-rescue-end. Khối begin chứa mã có thể gây ra exceptions, và khối rescue chứa mã để xử lý exceptions đó.

begin
  # Mã có thể gây ra exceptions
rescue SomeExceptionClass => e
  # Mã để xử lý exceptions
end

Ví dụ:

begin
  result = 10 / 0
rescue ZeroDivisionError => e
  puts "Lỗi: #{e.message}"
end

Trong ví dụ này, chúng ta cố gắng chia một số cho 0, điều này gây ra ZeroDivisionError. Khối rescue bắt lỗi này và in ra thông báo lỗi.

Sử dụng câu lệnh retry (Using retry Statement)

Câu lệnh retry cho phép chương trình thử lại một thao tác đã thất bại. Câu lệnh này thường được sử dụng trong khối rescue để thử lại thao tác gây ra exceptions.

attempts = 0

begin
  attempts += 1
  puts "Thử lần thứ #{attempts}"
  raise "Lỗi giả lập" if attempts < 3
rescue => e
  puts e.message
  retry if attempts < 3
end

Trong ví dụ này, chúng ta cố gắng thực hiện một thao tác và giả lập lỗi. Nếu số lần thử nhỏ hơn 3, chương trình sẽ thử lại thao tác đó.

Sử dụng câu lệnh raise (Using raise Statement)

Câu lệnh raise cho phép bạn tự động tạo ra exceptions. Bạn có thể sử dụng câu lệnh này để báo hiệu một điều kiện lỗi hoặc để tái tạo lại một exceptions đã bắt được.

def divide(x, y)
  raise ArgumentError, "Không thể chia cho 0" if y == 0
  x / y
end

begin
  result = divide(10, 0)
rescue ArgumentError => e
  puts "Lỗi: #{e.message}"
end

Trong ví dụ này, phương thức divide sẽ tạo ra ArgumentError nếu tham số y bằng 0.

Sử dụng câu lệnh ensure (Using ensure Statement)

Câu lệnh ensure cho phép bạn chỉ định mã sẽ luôn được thực thi, bất kể có exceptions xảy ra hay không. Điều này rất hữu ích để đảm bảo rằng các tài nguyên được giải phóng hoặc các hành động dọn dẹp được thực hiện.

file = File.open("example.txt", "w")

begin
  file.puts "Hello, World!"
rescue IOError => e
  puts "Lỗi: #{e.message}"
ensure
  file.close unless file.nil?
end

Trong ví dụ này, tệp sẽ luôn được đóng, bất kể có exceptions xảy ra hay không.

Sử dụng câu lệnh else (Using else Statement)

Câu lệnh else cho phép bạn chỉ định mã sẽ được thực thi nếu không có exceptions nào xảy ra trong khối begin.

begin
  result = 10 / 2
rescue ZeroDivisionError => e
  puts "Lỗi: #{e.message}"
else
  puts "Kết quả: #{result}"
end

Trong ví dụ này, nếu không có lỗi xảy ra, khối else sẽ được thực thi và in ra kết quả.

Sử dụng catchthrow (Catch and Throw)

Câu lệnh catchthrow cung cấp một cách để thoát ra khỏi các vòng lặp lồng nhau hoặc các lời gọi phương thức. Câu lệnh catch định nghĩa một khối mã có thể thoát ra bằng cách thực thi câu lệnh throw.

catch(:done) do
  (1..10).each do |i|
    if i == 5
      throw :done, "Đã tìm thấy số 5"
    end
  end
end

Trong ví dụ này, khi giá trị i bằng 5, câu lệnh throw sẽ thoát ra khỏi khối catch và trả về thông báo "Đã tìm thấy số 5".

Lớp Exception (Class Exception)

Lớp Exception là lớp cơ sở cho tất cả các exceptions trong Ruby. Bạn có thể tạo ra các lớp exceptions tùy chỉnh bằng cách kế thừa từ lớp StandardError hoặc một trong các lớp con của nó.

class MyCustomError < StandardError
  attr_reader :details

  def initialize(message, details)
    super(message)
    @details = details
  end
end

begin
  raise MyCustomError.new("Đã xảy ra lỗi tùy chỉnh", "Chi tiết lỗi")
rescue MyCustomError => e
  puts "Lỗi: #{e.message}"
  puts "Chi tiết: #{e.details}"
end

Trong ví dụ này, chúng ta tạo ra một lớp exceptions tùy chỉnh MyCustomError với thuộc tính details.

Các phương thức hữu ích của lớp Exception

Lớp Exception cung cấp nhiều phương thức hữu ích để làm việc với exceptions, bao gồm:

  • message: Trả về thông báo lỗi.
  • backtrace: Trả về mảng các chuỗi mô tả ngăn xếp gọi khi exceptions xảy ra.
  • cause: Trả về exceptions gốc nếu exceptions hiện tại được tạo ra bởi một exceptions khác.
begin
  raise "Lỗi ban đầu"
rescue => e
  raise "Lỗi thứ hai" rescue nil
end

begin
  raise "Lỗi thứ ba"
rescue => e
  puts "Thông báo lỗi: #{e.message}"
  puts "Ngăn xếp gọi: #{e.backtrace.join("\n")}"
  puts "Nguyên nhân: #{e.cause.message}" if e.cause
end

Kết luận

Xử lý exceptions là một phần quan trọng trong lập trình Ruby, giúp bạn quản lý và xử lý các lỗi xảy ra trong quá trình thực thi chương trình. Bằng cách sử dụng các câu lệnh retry, raise, ensure, else, catchthrow, cũng như lớp Exception, bạn có thể viết mã an toàn và đáng tin cậy hơn. Hãy tiếp tục khám phá và thực hành với xử lý exceptions trong Ruby để trở thành một lập trình viên giỏi hơn.

Avatar
Được viết bởi

TechMely Team

Gợi ý câu hỏi phỏng vấn

entry

What are the two types of Exceptions in Java? Which are the differences between them?

entry

Ruby on Rails là gì?

entry

Is there an equivalent of “continue” in Ruby?

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào