Skip to content

Commit

Permalink
Merge pull request #50 from driplineorg/dl3/exception-integration
Browse files Browse the repository at this point in the history
Dl3/exception integration
  • Loading branch information
laroque authored Jan 14, 2020
2 parents 4cf162f + d6e368d commit 07b44bf
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 137 deletions.
2 changes: 1 addition & 1 deletion dripline-cpp
1 change: 1 addition & 0 deletions dripline/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
from .endpoint import *
from .entity import *
from .interface import *
from .return_codes import *
from .throw_reply import *
17 changes: 4 additions & 13 deletions dripline/core/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,8 @@ def do_get_request(self, a_request_message):
return a_request_message.reply(201, "attribute error: {}".format(this_error))
else:
print('no specifier')
try:
the_value = self.on_get()
return a_request_message.reply(payload=scarab.to_param(the_value))
#TODO should work out exception details and make the following block more narrow
except Exception as e:
return a_request_message.reply( 100, "got an exception trying to on_get: {}".format(str(e)))
the_value = self.on_get()
return a_request_message.reply(payload=scarab.to_param(the_value))

def do_set_request(self, a_request_message):
a_specifier = a_request_message.specifier.to_string()
Expand Down Expand Up @@ -65,13 +61,8 @@ def do_cmd_request(self, a_request_message):
return a_request_message.reply(100, "error getting command's corresponding method: {}".format(str(e)))
the_kwargs = a_request_message.payload.to_python()
the_args = the_kwargs.pop('values', [])
try:
result = method_ref(*the_args, **the_kwargs)
return a_request_message.reply(payload=scarab.to_param(result))
except Exception as e:
#TODO: should be using a logger object here, right?
print("failure while trying to execute: {}(*{}, **{})".format(method_name, str(the_args), str(the_kwargs)))
return a_request_message.reply(100, "got an exception trying to execute cmd: {}".format(str(e)))
result = method_ref(*the_args, **the_kwargs)
return a_request_message.reply(payload=scarab.to_param(result))

def on_get(self):
'''
Expand Down
12 changes: 12 additions & 0 deletions dripline/core/return_codes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
__all__ = []

from _dripline.core import get_return_codes_map

__all__.append("get_return_codes_dict")
def get_return_codes_dict():
'''
Construct a dictionary of return codes, keyed on names (snake_case)
NOTE: return codes can be dynamically added at runtime, this function returns the current set when it is called; you probably when to call it when you need the codes rather than creating the dict earlier.
'''
return {a_return_code.name:a_return_code for (_, a_return_code) in get_return_codes_map().items()}
12 changes: 10 additions & 2 deletions dripline/core/throw_reply.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
__all__ = []

import scarab
from _dripline.core import _ThrowReply, DL_Success, set_reply_cache
from _dripline.core import DL_Success, set_reply_cache
from .return_codes import get_return_codes_dict

__all__.append('ThrowReply')
class ThrowReply(Exception):
def __init__(self, return_code=DL_Success(), message=DL_Success().description, payload=scarab.Param()):
Exception.__init__(self)
'''
return_code (_dripline.core.ReturnCode || string) : either a ReturnCode object, or the string name of a return code
message (string) : string to pass into the exception object, provides clarification of the particular exception
payload (scarab.Param) : any data to include in the payload of the reply message (in a Warning, should match the normal success data)
'''
Exception.__init__(self, message)
if isinstance(return_code, str):
return_code = get_return_codes_dict()[return_code]
set_reply_cache(return_code, message, payload)
18 changes: 7 additions & 11 deletions dripline/implementations/entity_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
import asteval # used for FormatEntity
import re # used for FormatEntity

from dripline.core import Entity, calibrate
# Dripline Exceptions currently unavailable
from dripline.core import Entity, calibrate, ThrowReply

# logging currently unavailable
# import logging
Expand All @@ -38,7 +37,6 @@ def __init__(self,
base_str (str): string used to generate SCPI commands; get will be of the form "base_str?"; set will be of the form "base_str <value>;base_str?"
'''
if base_str is None:
# exceptions.DriplineValueError
raise ValueError('<base_str> is required to __init__ SimpleSCPIEntity instance')
else:
self.cmd_base = base_str
Expand Down Expand Up @@ -67,8 +65,8 @@ def __init__(self, **kwargs):
SimpleSCPIEntity.__init__(self, **kwargs)

def on_set(self, value):
# exceptions.DriplineMethodNotSupportedError
raise Exception('setting not available for {}'.format(self.name))
#TODO exceptions.DriplineMethodNotSupportedError
raise ThrowReply('device_error', "endpoint '{}' does not support set".format(self.anme))


__all__.append('SimpleSCPISetEntity')
Expand All @@ -83,7 +81,7 @@ def __init__(self, **kwargs):

def on_get(self):
# exceptions.DriplineMethodNotSupportedError
raise Exception('getting not available for {}'.format(self.name))
raise ThrowReply('device_error', "endpoint '{}' does not support get".format(self.anme))

def on_set(self, value):
to_send = ['{} {};*OPC?'.format(self.cmd_base,value)]
Expand Down Expand Up @@ -122,18 +120,16 @@ def __init__(self,
self._extract_raw_regex = extract_raw_regex
self.evaluator = asteval.Interpreter()
if set_value_map is not None and not isinstance(set_value_map, (dict,str)):
# exceptions.DriplineValueError
raise ValueError("Invalid set_value_map config for {}; type is {} not dict".format(self.name, type(set_value_map)))
self._set_value_lowercase = set_value_lowercase
if isinstance(set_value_map, dict) and not set_value_lowercase:
# exceptions.DriplineValueError
raise ValueError("Invalid config option for {} with set_value_map and set_value_lowercase=False".format(self.name))

@calibrate()
def on_get(self):
if self._get_str is None:
# exceptions.DriplineMethodNotSupportedError
raise Exception('<{}> has no get string available'.format(self.name))
raise ThrowReply('device_error', "endpoint '{}' does not support get".format(self.anme))
result = self.service.send_to_device([self._get_str])
# logger.debug
print('result is: {}'.format(result))
Expand All @@ -144,7 +140,7 @@ def on_get(self):
# logger.error
print('matching returned none')
# exceptions.DriplineValueError
raise ValueError('returned result [{}] has no match to input regex [{}]'.format(first_result, self._extract_raw_regex))
raise ThrowReply('device_error', 'device returned unparsable result, [{}] has no match to input regex [{}]'.format(first_result, self._extract_raw_regex))
# logger.debug
print("matches are: {}".format(matches.groupdict()))
result = matches.groupdict()['value_raw']
Expand All @@ -153,7 +149,7 @@ def on_get(self):
def on_set(self, value):
if self._set_str is None:
# exceptions.DriplineMethodNotSupportedError
raise Exception('<{}> has no set string available'.format(self.name))
raise ThrowReply('device_error', "endpoint '{}' does not support set".format(self.anme))
if isinstance(value, str) and self._set_value_lowercase:
value = value.lower()
if self._set_value_map is None:
Expand Down
10 changes: 3 additions & 7 deletions dripline/implementations/ethernet_scpi_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ def __init__(self,
(ip,port) = re.findall(re_str,socket_info)[0]
socket_info = (ip,int(port))
if response_terminator is None or response_terminator == '':
# exceptions.DriplineValueError
raise ValueError("Invalid response terminator: <{}>! Expect string".format(repr(response_terminator)))
if not isinstance(cmd_at_reconnect, list) or len(cmd_at_reconnect)==0:
if cmd_at_reconnect is not None:
# exceptions.DriplineValueError
raise ValueError("Invalid cmd_at_reconnect: <{}>! Expect non-zero length list".format(repr(cmd_at_reconnect)))

self.alock = threading.Lock()
Expand Down Expand Up @@ -184,8 +182,7 @@ def _send_commands(self, commands):
if data.startswith(command):
data = data[len(command):]
elif not blank_command:
# exceptions.DriplineHardwareConnectionError
raise Exception("Bad ethernet query return: {}".format(data))
raise ThrowReply('device_error_connection', "Bad ethernet query return: {}".format(data))
# logger.info
print("sync: {} -> {}".format(repr(command),repr(data)))
all_data.append(data)
Expand All @@ -207,14 +204,13 @@ def _listen(self, blank_command=False):
break
# Special exception for disconnect of prologix box to avoid infinite loop
if data == '':
# exceptions.DriplineHardwareResponselessError
raise Exception("Empty socket.recv packet")
raise ThrowReply('device_error_no_response', "Empty socket.recv packet")
except socket.timeout:
# logger.warning
print("socket.timeout condition met; received:\n{}".format(repr(data)))
if blank_command == False:
# exceptions.DriplineHardwareResponselessError
raise Exception("Unexpected socket.timeout")
raise ThrowReply('device_error_no_response', "Unexpected socket.timeout")
terminator = ''
# logger.debug
print(repr(data))
Expand Down
7 changes: 7 additions & 0 deletions dripline/implementations/key_value_store.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from dripline.core import calibrate
from dripline.core import Entity
from dripline.core import ThrowReply
from dripline.core import get_return_codes_dict
from dripline.core import DL_WarningNoActionTaken
__all__ = []

__all__.append("KeyValueStore")
Expand All @@ -17,3 +20,7 @@ def on_get(self):
def on_set(self, new_value):
print("in K.V.S. on_set")
self._value = new_value

def throw_something(self):
print("in throw_something")
raise ThrowReply('device_error', "in throw_something method, rasing device_error")
4 changes: 1 addition & 3 deletions module_bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ set( PB_DRIPLINE_CORE_HEADERFILES
dripline_core/message_pybind.hh
dripline_core/message_virtual_pybind.hh
dripline_core/receiver_pybind.hh
dripline_core/reply_cache_pybind.hh
dripline_core/return_codes.hh
dripline_core/return_code_trampoline.hh
dripline_core/return_code_functions.hh
dripline_core/service_pybind.hh
dripline_core/service_trampoline.hh
dripline_core/scheduler_pybind.hh
dripline_core/throw_reply_pybind.hh
dripline_core/version_store_pybind.hh
)
set( PB_DRIPLINE_CORE_SOURCEFILES
dripline_core/return_code_functions.cc
dripline_core/dripline_core_namespace_pybind.cc
)
pybind11_add_module( _dripline ${PB_DRIPLINE_CORE_SOURCEFILES} )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include "error_pybind.hh"
#include "message_pybind.hh"
#include "receiver_pybind.hh"
#include "reply_cache_pybind.hh"
#include "return_codes_pybind.hh"
#include "scheduler_pybind.hh"
//#include "run_simple_service_pybind.hh"
#include "specifier_pybind.hh"
#include "service_pybind.hh"
#include "throw_reply_pybind.hh"
#include "version_store_pybind.hh"

PYBIND11_MODULE( _dripline, dripline_mod )
Expand Down
31 changes: 31 additions & 0 deletions module_bindings/dripline_core/reply_cache_pybind.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef DRIPLINE_PYBIND_REPLY_CACHE_HH_
#define DRIPLINE_PYBIND_REPLY_CACHE_HH_

#include "reply_cache.hh"

#include "pybind11/pybind11.h"
#include "pybind11/iostream.h"

namespace dripline_pybind
{

std::list< std::string> export_throw_reply( pybind11::module& mod )
{
std::list< std::string > all_items;

all_items.push_back( "set_reply_cache" );
mod.def( "set_reply_cache",
[](const dripline::return_code& a_code, const std::string& a_message, const scarab::param& a_payload) {
dripline::set_reply_cache( a_code, a_message, a_payload.clone());
},
pybind11::arg( "return_code" ),
pybind11::arg( "return_message" ),
pybind11::arg( "payload" ),
"set the reply cache with the desired information"
);

return all_items;
}
} /* namespace dripline_pybind */

#endif /* DRIPLINE_PYBIND_REPLY_CACHE_HH_ */
26 changes: 0 additions & 26 deletions module_bindings/dripline_core/return_code_functions.cc

This file was deleted.

11 changes: 0 additions & 11 deletions module_bindings/dripline_core/return_code_functions.hh

This file was deleted.

4 changes: 2 additions & 2 deletions module_bindings/dripline_core/return_codes_pybind.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#include "return_codes.hh"
#include "return_code_trampoline.hh"

#include "return_code_functions.hh"

#include "pybind11/pybind11.h"
#include "pybind11/stl.h"

Expand Down Expand Up @@ -47,6 +45,8 @@ namespace dripline_pybind

all_items.push_back( "get_return_code_values" );
mod.def( "get_return_code_values", &dripline::get_return_code_values );
all_items.push_back( "get_return_codes_map" );
mod.def( "get_return_codes_map", &dripline::get_return_codes_map );

// now bind all of the existing dripline return codes so we can use them
ADD_DRIPLINE_RET_CODE( success, Success )
Expand Down
60 changes: 0 additions & 60 deletions module_bindings/dripline_core/throw_reply_pybind.hh

This file was deleted.

0 comments on commit 07b44bf

Please sign in to comment.