<commit_before>#!/usr/bin/env python

# XenAPI plugin boilerplat code

import sys, xmlrpclib, XenAPI

class Failure:
    def __init__(self, code, params):
        self.code = code
        self.params = params
    def __str__(self):
        s = { 'Status': 'Failure', 'ErrorDescription': [ self.code ] + self.params }        
        return xmlrpclib.dumps((s, ), "", True)

def dispatch(fn_table):
    if len(sys.argv) <> 2:
        raise "Incorrect number of commandline arguments"
    params, methodname = xmlrpclib.loads(sys.argv[1])
    session_id = params[0]
    args = params[1]
    try:
        if methodname in fn_table.keys():
            x = XenAPI.xapi_local()
            x._session = session_id
            result = fn_table[methodname](x, args)
            s = { 'Status': 'Success', 'Value': result }
            print xmlrpclib.dumps((s, ), "", True)
        else:
            raise Failure("UNKNOWN_XENAPI_PLUGIN_FUNCTION", [ methodname ])
    except Failure, e:
        print str(e)<commit_msg>Here is my modified XenAPIPlugin.py. Now it catches exceptions in the plugin method, and returns their class and error message to the caller in the XMLRPC ErrorDescription field. I've also refactored the control flow a little bit, even though this ought to be a separate optional change...<commit_after>#!/usr/bin/python

# XenAPI python plugin boilerplate code

import sys, xmlrpclib, XenAPI


def success_message(result):
    rpcparams = { 'Status': 'Success', 'Value': result }
    return xmlrpclib.dumps((rpcparams, ), '', True)

def failure_message(description):
    rpcparams = { 'Status': 'Failure', 'ErrorDescription': description }
    return xmlrpclib.dumps((rpcparams, ), '', True)

def dispatch(fn_table):
    if len(sys.argv) <> 2:
        raise "Incorrect number of commandline arguments"
    params, methodname = xmlrpclib.loads(sys.argv[1])
    session_id = params[0]
    args = params[1]
    if methodname in fn_table:
        x = XenAPI.xapi_local()
        x._session = session_id
        try:
            result = fn_table[methodname](x, args)
            print success_message(result)
        except SystemExit:
            # SystemExit should not be caught, as it is handled elsewhere in the plugin system.
            raise
        except Exception, e:
            print failure_message(['XENAPI_PLUGIN_EXCEPTION',
                                   methodname, e.__class__.__name__, str(e)])
    else:
        print failure_message(['UNKNOWN_XENAPI_PLUGIN_FUNCTION', methodname])
{'fraction_non_alphanumeric': 0.10536779324055666, 'fraction_numerical': 0.0031809145129224653, 'mean_word_length': 2.7608370702541105, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3733792', 'n_tokens_mistral': 757, 'n_tokens_neox': 735, 'n_words': 214}