Skip to content

Commit 77e18a9

Browse files
committed
Error handling optimiyed
1 parent 20ff3e0 commit 77e18a9

File tree

5 files changed

+49
-35
lines changed

5 files changed

+49
-35
lines changed

TODOS

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,27 @@ Documentation:
1010
When an element returns None, subsequent
1111
elements are still triggered
1212

13-
Exceptions:
13+
Logging:
14+
15+
#1 INFO:
16+
Ordinary debug trace messages
17+
Can be switched on or off by the user (checkbox in element configuration)
18+
Implementation in own code is optional
19+
20+
21+
#2 WARNING:
22+
Signalize a failed execution
23+
Can be switched on or off by the user (checkbox in element configuration)
24+
A log entry of this type is created when the element returns data of type PythonicError
25+
Implementation in own code is optional
26+
27+
#3 Critical (Unhandled exception):
28+
Is signalized in the GUI an (,,Exception occured, open log for details)
29+
Log entry (type ERROR) is made
30+
Is always active (implementation not optional)
31+
32+
33+
Error handling:
1434

1535
#1
1636
Elements should throw an exception when configuration
@@ -21,16 +41,19 @@ Documentation:
2141
and only throw critical exceptions.
2242

2343
#3
24-
If appropriate, the result of a operation (if successfull or not) should
25-
be forwarded to subsequent elements in order to react to
26-
a possible unsuccesfull operation. When it was not possible to process the input data, return the PythonicError with related information.
27-
Combine this with logging.warning (preferred) or logging.error.
44+
The result of a operation (if successfull or not (see #2)) should always
45+
be forwarded to subsequent elements in order to react to a possible failed call.
46+
If the result of a failed call could be processed by an subsequent element,
47+
it should be wrapped inside the PythonicError type.
2848

2949
#4
30-
Avoid to use logging.error or logging.warning without the other mechanisms as those methods will only write to the log.
50+
In case of a failed call, a meaningful message or the exception text should returned
51+
(PythonicError as data parameter in returned Record type)
3152

53+
#4
54+
Dont to use logging.error or logging.warning as it has no effect if used in combination with multiprocessing.
3255

33-
Check exception rules
56+
1917141915:AAHRe-CZhv8fIv6bQzHMipgYPuVnQbQGxtY
3457

3558
CCXT Method: Try to optimize large if-else areas for parsing config
3659

src/Pythonic/executables/email.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ def execute(self):
5252

5353
if not sender:
5454
raise Exception('Sender missing in configuration')
55-
5655
if not password:
5756
raise Exception('Password missing in configuration')
58-
5957
if not url:
6058
raise Exception('URL missing in configuration')
6159
if not port:
@@ -64,15 +62,15 @@ def execute(self):
6462

6563
if isinstance(self.inputData, dict):
6664
if not 'recipient' in self.inputData or not isinstance(self.inputData['recipient'], str):
67-
recordDone = Record(None, message='Key "recipient" not found or not of type string')
65+
recordDone = Record(PythonicError('Key error, see log for details'), message='Key "recipient" not found or not of type string')
6866
self.return_queue.put(recordDone)
6967
return
7068
if not 'subject' in self.inputData or not isinstance(self.inputData['subject'], str):
71-
recordDone = Record(None, message='Key "subject" not found or not of type string')
69+
recordDone = Record(PythonicError('Key error, see log for details'), message='Key "subject" not found or not of type string')
7270
self.return_queue.put(recordDone)
7371
return
7472
if not 'message' in self.inputData or not isinstance(self.inputData['message'], str):
75-
recordDone = Record(None, message='Key "subject" not found or not of type string')
73+
recordDone = Record(PythonicError('Key error, see log for details'), message='Key "subject" not found or not of type string')
7674
self.return_queue.put(recordDone)
7775
return
7876

@@ -85,14 +83,11 @@ def execute(self):
8583

8684
attachments = self.inputData['attachment']
8785

88-
8986
else:
90-
recordDone = Record(None, message='Config missing')
87+
recordDone = Record(PythonicError('Config missing'), message='Config missing')
9188
self.return_queue.put(recordDone)
9289
return
9390

94-
95-
9691
msg = EmailMessage()
9792
msg['Subject'] = subject
9893
msg['From'] = sender

src/Pythonic/executables/sqlite.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import time, queue, sqlite3, logging
1+
import time, queue, sqlite3
22
try:
33
from element_types import Record, Function, ProcCMD, GuiCMD, PythonicError
44
except ImportError:
@@ -48,7 +48,6 @@ def execute(self):
4848
try:
4949
cur.execute(self.inputData)
5050
except Exception as e:
51-
logging.warning(e)
5251
recordDone = Record(PythonicError(e), 'Query failed')
5352
self.return_queue.put(recordDone)
5453
con.close()

src/Pythonic/executables/telegram.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
import logging, queue
1+
import queue
22
from telegram import Update
33
from telegram.ext import Updater, CommandHandler, CallbackContext, MessageHandler, Filters
44

55
try:
6-
from element_types import Record, Function, ProcCMD, GuiCMD, SetPersist
6+
from element_types import Record, Function, ProcCMD, GuiCMD, SetPersist, PythonicError
77
except ImportError:
8-
from Pythonic.element_types import Record, Function, ProcCMD, GuiCMD, SetPersist
8+
from Pythonic.element_types import Record, Function, ProcCMD, GuiCMD, SetPersist, PythonicError
99

10-
try:
11-
from element_types import Record, Function, ProcCMD, GuiCMD
12-
except ImportError:
13-
from Pythonic.element_types import Record, Function, ProcCMD, GuiCMD
1410

1511
class Element(Function):
1612

@@ -89,15 +85,11 @@ def message(update, context):
8985
guitext = GuiCMD("Sending data: " + str(cmd.data))
9086
self.return_queue.put(guitext)
9187

92-
for chat_id in chat_ids:
88+
for chat_id in chat_ids.copy():
9389
try:
9490
dispatcher.bot.send_message(chat_id=chat_id, text=str(cmd.data))
9591
except Exception as e:
96-
# BAUSTELLE # Return Error Element ?
97-
logging.error(e)
9892
chat_ids.discard(chat_id)
99-
logging.warning('ChatId removed')
100-
101-
93+
self.return_queue.put(Record(PythonicError(e), 'Error sending message, related chat id removed'))
10294

10395
cmd = None

src/Pythonic/execution_operator.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111

1212
try:
13-
from element_types import Record, ProcCMD, GuiCMD, GuiException
13+
from element_types import Record, ProcCMD, GuiCMD, GuiException, PythonicError
1414
except ImportError:
15-
from Pythonic.element_types import Record, ProcCMD, GuiCMD, GuiException
15+
from Pythonic.element_types import Record, ProcCMD, GuiCMD, GuiException, PythonicError
1616

1717

1818

@@ -177,7 +177,7 @@ def run(self):
177177

178178
class OperatorElementOpDone(QRunnable):
179179

180-
def __init__(self, config, id, record, identifier, operator):
180+
def __init__(self, config, id, record : Record, identifier, operator):
181181
super(OperatorElementOpDone, self).__init__()
182182

183183

@@ -194,8 +194,13 @@ def run(self):
194194

195195
cfgElement = [x for x in self.currentConfig if x['Id'] == self.id][0]
196196

197+
198+
197199
if cfgElement['Config']['GeneralConfig']['Logging'] and self.record.message: # Log Message enabled
198-
logging.info('{} - {}'.format(cfgElement['ObjectName'], self.record.message))
200+
if isinstance(self.record.data, PythonicError):
201+
logging.warning('{} - {}'.format(cfgElement['ObjectName'], self.record.message))
202+
else:
203+
logging.info('{} - {}'.format(cfgElement['ObjectName'], self.record.message))
199204

200205
data = {
201206
'Id' : cfgElement['Id'],

0 commit comments

Comments
 (0)