Custom Exceptions in Ruby and Python
Creating your own exceptions is a good thing. It lets you catch something very specific without the need to inspect more generic exceptions for the right messages every time.
Catching All Exceptions
Catching all exceptions is bad. Why? Have a look at the following:
Given the code above, it’s nearly impossible to know why your code fails. At best, there are two reasons for the failure: the file doesn’t exist; or you’re attempting to write to a file when you’ve opened it as read-only. In reality, there are probably many more exceptions that could be generated, and you probably want to handle them all differently.
Custom Exceptions in Python
Let’s look at Python’s
ncclient library. What if we want to catch
ncclient doesn’t raise an exception for this. To
see how we can catch an unauthorized command, let’s create a small
Now if a user uses our library, they’ll get the appropriate error for
trying to configure something for which they are not authorized. After
if statement, we re-raise the exception with a bare
that we don’t skip over something other than an unauthorized command.
You could catch many other types of exceptions at the same time, but I’ve ommitted them for brevity.
Custom Exceptions in Ruby
Now let’s look at custom exceptions in Ruby. We’ll do this example as a
simple script instead of assuming it’s a library. Let’s assume that a
bob with the password
bob exists on the switch but is not
allowed to change configuration on the device. This example assumes a
Brocade VDX is the target device, but the principles remain the same
regardless of vendor.
If we were to execute this script, this is what we’d get:
$ ruby custom_exception.rb custom_exception.rb:21:in `rescue in block in <main>': User is not authorized for this RPC. (UnauthorizedError) from harbl.rb:10:in `block in <main>' from /home/tyler/.rvm/gems/[email protected]/gems/net-netconf-0.4.3/lib/net/netconf/transport.rb:27:in `initialize' from /home/tyler/.rvm/gems/[email protected]/gems/net-netconf-0.4.3/lib/net/netconf/ssh.rb:21:in `initialize' from custom_exception.rb:9:in `new' from custom_exception.rb:9:in `<main>'
I hope you can see how useful creating your own exceptions can be. It makes it much easier to diagnose and debug when a user (inevitably) reports a bug in your software.