Những ngoại lệ phổ biến trong Ruby on Rails
Bài đăng này đã không được cập nhật trong 6 năm
Trong khi làm việc với Ruby, chúng ta rất hay gặp phải các thông báo lỗi về Exception, sau đây là sơ đồ phân cấp các Exception trong Ruby với class Exception
là gốc chính:
Exception
NoMemoryError
ScriptError
LoadError
NotImplementedError
SyntaxError
SignalException
Interrupt
StandardError
ArgumentError
IOError
EOFError
IndexError
LocalJumpError
NameError
NoMethodError
RangeError
FloatDomainError
RegexpError
RuntimeError
SecurityError
SystemCallError
SystemStackError
ThreadError
TypeError
ZeroDivisionError
SystemExit
Trong đó ta có thể thấy được rằng StandardError
là một superclass
với nhiều class con chứa các lỗi phổ biến nhất mà chúng ta thường gặp, sau đây chúng ta sẽ cùng tìm hiểu về các lỗi ấy.
NoMethodError
undefined method `grade' for nil:NilClass
undefined method `<<' for {}:Hash
Khi một phương thức được gọi cho 1 đối tượng cụ thể không tồn tại thì lỗi này được trả về, phổ biến nhất là nil:Nilclass
[1] pry(main)> nil.grade
NoMethodError: undefined method `grade' for nil:NilClass
[2] pry(main)>
Nếu không có yêu cầu đặc biệt cho việc xử lý kết quả (ví dụ như chỉ dùng kết quả để show) thì bạn hãy sử dụng try
để tránh lỗi này:
[2] pry(main)> nil.try(:something)
=> nil
[3] pry(main)>
NameError
undefined local variable or method `grade' for #
uninitialized constant Report
Lỗi trên xảy ra khi 1 biến không được khởi tạo, cách sửa lỗi này đó là gán giá trị khởi tạo cho nó.
NoMethodError(cho private method)
[6] pry(main)> u.password_complexity
NoMethodError: private method `password_complexity' called for #<User:0x00000016063680>
Lỗi này ta có thể gặp khi truy cập trực tiếp một private object method từ một object.
Ta có thể tránh việc này bằng cách chuyển method sang public
hoặc dùng send
:
[7] pry(main)> u.send(:password_complexity)
=> nil
[8] pry(main)>
ActiveRecord::RecordNotFound
[8] pry(main)> User.find 10000
User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 10000 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=10000
Lỗi xảy ra khi ra muốn truy xuất một bản ghi có id không tồn tại trong DB bằng find chảng hạn.Để tránh lỗi này chúng ta có thể sử dụng find_by
hoặc where
:
[2] pry(main)> User.find_by_id(params[:id])
=> nil
[3] pry(main)> User.find_by(id: params[:id])
=> nil
[4] pry(main)> User.where(id: params[:id]).first
=> nil
TypeError
[9] pry(main)> "1" + 2
TypeError: no implicit conversion of Fixnum into String
Khi cộng một String và 1 số Integer thì sẽ phát sinh lỗi này, lỗi này có thể xuất hiện khi ta thực hiện thao tác với nhiều loại khác nhau như String, FixNum, Array, Hash, Float
,
để tránh lỗi này thì ta nên convert các object về cùng 1 kiểu:
[3] pry(main)> "1" + 2
TypeError: no implicit conversion of Fixnum into String
from (pry):3:in `+'
[4] pry(main)> "1".to_i + 2
=> 3
[5] pry(main)>
ArgumentError
wrong number of arguments (0 for 1)
Lỗi này xảy ra khi ta gọi hàm mà truyền vào số lượng tham số không chính xác như khi định nghĩa hàm, chảng hạn:
my_grade = student(college, grade)
def student(college) # Argument error
end
def student(college, grade = 0) # works fine as grade is assigned 0.
end
Truyền đúng số lượng tham số hoặc xét giá trị mặc định cho những tham số có thể không nhất thiết cần truyền khi gọi hàm là cách giải quyết lỗi này.
All rights reserved