[Libguestfs] [PATCH libnbd v3] python: Raise a custom exception containing error string and errno.

Eric Blake eblake at redhat.com
Fri Jun 28 18:53:11 UTC 2019


On 6/28/19 1:27 PM, Richard W.M. Jones wrote:
> Previously errors caused a RuntimeException to be raised.  This commit
> defines a custom exception (nbd.Error) which has two parameters, the
> required error string, and the optional errno (which may be 0 if
> unavailable).
> 
> For example:
> 
> $ ./run nbdsh -c 'h.pread(0, 0)'
> Traceback (most recent call last):
>   File "/usr/lib64/python3.7/runpy.py", line 193, in _run_module_as_main
>     "__main__", mod_spec)
>   File "/usr/lib64/python3.7/runpy.py", line 85, in _run_code
>     exec(code, run_globals)
>   File "/home/rjones/d/libnbd/python/nbd.py", line 1163, in <module>
>     nbdsh.shell()
>   File "/home/rjones/d/libnbd/python/nbdsh.py", line 62, in shell
>     exec (c)
>   File "<string>", line 1, in <module>
>   File "/home/rjones/d/libnbd/python/nbd.py", line 483, in pread
>     return libnbdmod.pread (self._o, count, offset, flags)
> nbd.Error: nbd_pread: invalid state: START: the handle must be connected and finished handshaking with the server: Transport endpoint is not connected (ENOTCONN)

Cool - in the time I spent writing my reply to v2 1/1, your reaction to
my reply on 0/1 figured out the way to get what we want:


> @@ -3917,6 +3938,36 @@ Read the libnbd(3) man page to find out how to use the API.
>  
>  import libnbdmod
>  
> +# Re-export Error exception as nbd.Error, adding some methods.
> +from libnbdmod import Error

Implement all the cool stuff in pure Python on top of the bare-bones
minimum :)  Lots less hassle than writing it in C code.  I like it!

> +
> +Error.__doc__ = '''
> +Exception thrown when the underlying libnbd call fails.
> +
> +This exception has two properties to query the error.  Use
> +the .string property to return a printable string containing
> +the error message.  Use the .errno property to return a
> +Python errno (which may be None in some cases if the error
> +did not correspond to a system call failure).
> +'''
> +
> +Error.string = property (lambda self: self.args[0])
> +
> +def _errno (self):
> +    import errno
> +    try:
> +        return errno.errorcode[self.args[1]]
> +    except KeyError:
> +        return None
> +Error.errno = property (_errno)
> +
> +def _str (self):
> +    if self.errno:
> +        return (\"%%s (%%s)\" %% (self.string, self.errno))
> +    else:
> +        return (\"%%s\" %% self.string)
> +Error.__str__ = _str

Looks good to me now!  Thanks for figuring this out while I was
struggling with reading lots of documentation on C bindings.

ACK

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20190628/fbe29ca1/attachment.sig>


More information about the Libguestfs mailing list