Skip to content

Instantly share code, notes, and snippets.

@bachkukkik
Last active December 14, 2020 07:27
Show Gist options
  • Save bachkukkik/b29d00df1ae979c3142254db92fa832e to your computer and use it in GitHub Desktop.
Save bachkukkik/b29d00df1ae979c3142254db92fa832e to your computer and use it in GitHub Desktop.
push errors for slack notification
import os
from functools import wraps, partial
from inspect import signature
# https://stackoverflow.com/questions/55748500/simulate-the-assignment-of-function-arguments-to-args-and-kwargs
try:
module = os.path.basename(__file__)
except:
module = 'some_plain_str'
dct_slack_url = {
module:'https://hooks.slack.com/services/<module>'
}
def slack_notification(position, e, module, dct_error):
"""
push error to dct_slack_url['module']
Normally, slack_notification should be handled by @errors_pusher
Parameters
--------
position: str or function.__name__
e: error object
module: str or os.path.basename(__file__)
dct_error: dict from inspect.getcallargs(function, args)
"""
url = dct_slack_url[module]
msg = {"text": f"ERROR!\nmodule: {module}\nposition: {position}\nerror msg: {e}\nparameters: {dct_error}"}
requests.post(url, data=json.dumps(msg))
def errors_pusher(function, module=module):
"""
Return wrapper_function
@errors_pusher should be used as a decorator to function(*args,**kwargs).
errors_pusher will push slack_notification should the error occur
For custom decorator:
1. see example#1
2. https://stackoverflow.com/questions/5929107/decorators-with-parameters
Parameters
--------
function: a decorated function
module: str or os.path.basename(__file__)
Example
--------
### example0: normal decorator
>>> @errors_pusher
... def plus_one(i: int):
... return i+1
...
>>> plus_one('asd')
printed error message
### example1: custom decorator
>>> module = 'kukkik'
>>> dct_slack_url = {module: '< https://hooks.slack.com/services/... >'} # or add new key-value if necessary
>>> custom_decorator = partial(errors_pusher, module=module)
>>> @custom_decorator
... def mul_one(i: int):
... return i+1
...
>>> mul_one('asd')
printed error message
"""
@wraps(function)
def wrapper_function(*args,**kwargs):
try:
return function(*args,**kwargs)
except Exception as e:
dct_error = dict(signature(function).bind(*args, **kwargs).arguments)
for k,v in dct_error.items():
if len(str(v))>100:
dct_error.update({k:f"{str(v)[:80]}.....{str(v)[-20:]}"})
print(f'{module} error on : {function.__name__}', e, dct_error)
e = str(e)
slack_notification(function.__name__, e, module, dct_error)
return wrapper_function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment