Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions build/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ def _add_python_return_type(f):
f['returns_python'] = f['returns']
return f

def _add_is_error_handling(f):
'''Adds is_error_handling information to the function metadata if it isn't already defined. Defaults to False.'''
# TODO(marcoskirsch): The information is added in functions_addon.py. I think we can instead infer from method
Copy link
Contributor

@texasaggie97-zz texasaggie97-zz Sep 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My two <pick your currency> is this way (being explicit) is less error prone.

# name but I am not sure if it's a good idea (heuristics vs being explicit - both error prone in different ways).
try:
f['is_error_handling']
except KeyError:
# Not populated, assume False
f['is_error_handling'] = False
return f

def _add_buffer_info(parameter):
'''Adds buffer information to the parameter metadata iff 'size' is defined else assume not a buffer'''
try:
Expand All @@ -143,6 +154,7 @@ def add_all_metadata(functions):
_add_python_method_name(functions[f], f)
_add_ctypes_return_type(functions[f])
_add_python_return_type(functions[f])
_add_is_error_handling(functions[f])
for p in functions[f]['parameters']:
_add_python_parameter_name(p)
_add_python_type(p)
Expand Down
28 changes: 20 additions & 8 deletions build/templates/errors.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,30 @@ class DriverNotInstalledError(Exception):
super(DriverNotInstalledError, self).__init__('The ${driver_name} runtime is not installed. Please visit http://www.ni.com/downloads/drivers/ to download and install it.')


def handle_error(session, code, ignore_warnings):
def handle_error(session, code, ignore_warnings, is_error_handling):
'''handle_error

Helper function for handling errors returned by ${module_name}.Library.
It calls back into the session to get the corresponding error description
and raises if necessary.
'''

if _is_success(code) or (_is_warning(code) and ignore_warnings):
return
try:

if is_error_handling:
# The caller is in the midst of error handling. Don't get the
# error description in this case as that could itself fail.
description = "Failed to retrieve error description."
warnings.warn(description)
else:
description = session.get_error_description(code)
except Exception as e:
# TODO(marcoskirsch): Log this exception.
description = ""
if (_is_error(code)):

if _is_error(code):
raise Error(code, description)
if (_is_warning(code)):
warnings.warn(${module_name_class}Warning(code, description))

assert _is_warning(code)
warnings.warn(${module_name_class}Warning(code, description))


warnings.filterwarnings("always", category=${module_name_class}Warning)
11 changes: 8 additions & 3 deletions build/templates/session.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,18 @@ context_name = 'acquisition' if c['direction'] == 'input' else 'generation'
_, error_string = self._get_error()
return error_string
except errors.Error:
pass

try:
'''
It is expected for _get_error to raise when the session is invalid
(IVI spec requires GetError to fail).
Use _get_error_message instead. It doesn't require a session.
'''
error_string = self._get_error_message(error_code)
return error_string
except errors.Error:
return "Failed to retrieve error description."

''' These are code-generated '''
% for func_name in sorted(functions):
Expand All @@ -216,17 +221,17 @@ context_name = 'acquisition' if c['direction'] == 'input' else 'generation'
% endfor
% if ivi_dance_parameter is None:
error_code = self.library.${c_function_prefix}${func_name}(${helper.get_library_call_parameter_snippet(f['parameters'])})
errors.handle_error(self, error_code, ignore_warnings=False)
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=${f['is_error_handling']})
${helper.get_method_return_snippet(f['parameters'])}
% else:
${ivi_dance_size_parameter['python_name']} = 0
${ivi_dance_parameter['ctypes_variable_name']} = None
error_code = self.library.${c_function_prefix}${func_name}(${helper.get_library_call_parameter_snippet(f['parameters'])})
errors.handle_error(self, error_code, ignore_warnings=True)
errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=${f['is_error_handling']})
${ivi_dance_size_parameter['python_name']} = error_code
${ivi_dance_parameter['ctypes_variable_name']} = ctypes.cast(ctypes.create_string_buffer(${ivi_dance_size_parameter['python_name']}), ctypes_types.${ivi_dance_parameter['ctypes_type']})
error_code = self.library.${c_function_prefix}${func_name}(${helper.get_library_call_parameter_snippet(f['parameters'])})
errors.handle_error(self, error_code, ignore_warnings=False)
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=${f['is_error_handling']})
${helper.get_method_return_snippet(f['parameters'])}
% endif
% endfor
Expand Down
27 changes: 0 additions & 27 deletions docs/nidmm/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2086,33 +2086,6 @@ nidmm.Session methods



.. function:: error_message(error_code, error_message)

Takes the **Error\_Code** returned by the instrument driver functions,
interprets it, and returns it as a user-readable string.




:param error_code:


The **error\_code** returned from the instrument. The default is 0,
indicating VI\_SUCCESS.



:type error_code: int

:rtype: int
:return:


The error information formatted into a string.




.. function:: error_query(error_code, error_message)

Reads an **Error\_Code** and message from the DMM error queue. National
Expand Down
30 changes: 0 additions & 30 deletions docs/niswitch/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1257,36 +1257,6 @@ niswitch.Session methods

:type maximum_time_ms: int

.. function:: error_message(error_code, error_message)

Converts an error code returned by NI-SWITCH into a user-readable
string. Generally this information is supplied in error out of any
NI-SWITCH VI. Use :py:func:`niswitch.error_message` for a static lookup of an
error code description.




:param error_code:


Status code returned by any NI-SWITCH function. Default Value: 0
(VI\_SUCCESS)



:type error_code: int

:rtype: int
:return:


The error information formatted into a string. You must pass a ViChar
array with at least 256 bytes.




.. function:: error_query(error_code, error_message)

This function reads an error code and a message from the instrument's
Expand Down
28 changes: 20 additions & 8 deletions generated/nidmm/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,30 @@ def __init__(self):
super(DriverNotInstalledError, self).__init__('The NI-DMM runtime is not installed. Please visit http://www.ni.com/downloads/drivers/ to download and install it.')


def handle_error(session, code, ignore_warnings):
def handle_error(session, code, ignore_warnings, is_error_handling):
'''handle_error

Helper function for handling errors returned by nidmm.Library.
It calls back into the session to get the corresponding error description
and raises if necessary.
'''

if _is_success(code) or (_is_warning(code) and ignore_warnings):
return
try:

if is_error_handling:
# The caller is in the midst of error handling. Don't get the
# error description in this case as that could itself fail.
description = "Failed to retrieve error description."
warnings.warn(description)
else:
description = session.get_error_description(code)
except Exception as e:
# TODO(marcoskirsch): Log this exception.
description = ""
if (_is_error(code)):

if _is_error(code):
raise Error(code, description)
if (_is_warning(code)):
warnings.warn(NidmmWarning(code, description))

assert _is_warning(code)
warnings.warn(NidmmWarning(code, description))


warnings.filterwarnings("always", category=NidmmWarning)
20 changes: 1 addition & 19 deletions generated/nidmm/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def __init__(self, library_name, library_type):
self._func_lock = threading.Lock()
# We cache the cfunc object from the ctypes.CDLL object
self.niDMM_Abort_cfunc = None
self.niDMM_ClearError_cfunc = None
self.niDMM_ClearInterchangeWarnings_cfunc = None
self.niDMM_ConfigureACBandwidth_cfunc = None
self.niDMM_ConfigureADCCalibration_cfunc = None
Expand Down Expand Up @@ -92,7 +91,6 @@ def __init__(self, library_name, library_type):
self.niDMM_SetAttributeViString_cfunc = None
self.niDMM_UnlockSession_cfunc = None
self.niDMM_close_cfunc = None
self.niDMM_error_message_cfunc = None
self.niDMM_error_query_cfunc = None
self.niDMM_reset_cfunc = None
self.niDMM_revision_query_cfunc = None
Expand All @@ -112,14 +110,6 @@ def niDMM_Abort(self, vi): # noqa: N802
self.niDMM_Abort_cfunc.restype = nidmm.python_types.ViStatus
return self.niDMM_Abort_cfunc(vi)

def niDMM_ClearError(self, vi): # noqa: N802
with self._func_lock:
if self.niDMM_ClearError_cfunc is None:
self.niDMM_ClearError_cfunc = self._library.niDMM_ClearError
self.niDMM_ClearError_cfunc.argtypes = [ViSession_ctype] # noqa: F405
self.niDMM_ClearError_cfunc.restype = nidmm.python_types.ViStatus
return self.niDMM_ClearError_cfunc(vi)

def niDMM_ClearInterchangeWarnings(self, vi): # noqa: N802
with self._func_lock:
if self.niDMM_ClearInterchangeWarnings_cfunc is None:
Expand Down Expand Up @@ -484,7 +474,7 @@ def niDMM_GetErrorMessage(self, vi, error_code, buffer_size, error_message): #
with self._func_lock:
if self.niDMM_GetErrorMessage_cfunc is None:
self.niDMM_GetErrorMessage_cfunc = self._library.niDMM_GetErrorMessage
self.niDMM_GetErrorMessage_cfunc.argtypes = [ViSession_ctype, ViStatus_ctype, ViInt32_ctype, ctypes.POINTER(ViChar_ctype)] # noqa: F405
self.niDMM_GetErrorMessage_cfunc.argtypes = [ViSession_ctype, ViStatus_ctype, ViInt32_ctype, ViString_ctype] # noqa: F405
self.niDMM_GetErrorMessage_cfunc.restype = nidmm.python_types.ViStatus
return self.niDMM_GetErrorMessage_cfunc(vi, error_code, buffer_size, error_message)

Expand Down Expand Up @@ -704,14 +694,6 @@ def niDMM_close(self, vi): # noqa: N802
self.niDMM_close_cfunc.restype = nidmm.python_types.ViStatus
return self.niDMM_close_cfunc(vi)

def niDMM_error_message(self, vi, error_code, error_message): # noqa: N802
with self._func_lock:
if self.niDMM_error_message_cfunc is None:
self.niDMM_error_message_cfunc = self._library.niDMM_error_message
self.niDMM_error_message_cfunc.argtypes = [ViSession_ctype, ViStatus_ctype, ctypes.POINTER(ViChar_ctype)] # noqa: F405
self.niDMM_error_message_cfunc.restype = nidmm.python_types.ViStatus
return self.niDMM_error_message_cfunc(vi, error_code, error_message)

def niDMM_error_query(self, vi, error_code, error_message): # noqa: N802
with self._func_lock:
if self.niDMM_error_query_cfunc is None:
Expand Down
Loading