I'm using a python decorator to handle exceptions in my flask app.
decorators.py
def exception(original_function=None, message='Some error occurred on our end.', app=None):
def decorator(function):
#functools.wraps(function)
def wrapper_function(*args, **kwargs):
try:
return function(*args, **kwargs)
except Exception as e:
handler(app, e)
return internal_error(message)
return wrapper_function
The handler function captures the exception details and logs or displays them.
def handler(app, e='Exception'):
exc_type, exc_obj, exc_tb = sys.exc_info()
exc_type, filename, line_no = exc_type, exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno
app.logger.error(f'\n+{"-" * 64}\n'
'| Exception details:\n'
f'| Message: {e}\n'
f'| Type:\t\t{exc_type}\n'
f'| File:\t\t{filename}\n'
f'| Line No:\t\t{line_no}\n'
f'+{"-" * 64}\n')
Then I use it in flask routes as:
route.py
#bp.route('/initialize/<string:uuid>/<string:method>', methods=['POST'])
#exception(app=current_app)
def initialize(uuid=None, method=None):
if not uuid:
return bad_request('No UUID')
Right now, the handler does work, however, it logs that the exception originated from decorators.py on the return function(*args, **kwargs) line. How can I log the actual file and line the exception originated?
Here is an output of the log.
+----------------------------------------------------------------
| Exception details:
| Message: Required PAYPAL_CLIENT_ID and PAYPAL_CLIENT_SECRET.
| Type: <class 'paypalrestsdk.exceptions.MissingConfig'>
| File: /app/decorators.py
| Line No: 16
+----------------------------------------------------------------
Related
This is the code in which I am getting error .Same operation is achieved by using SQLAlchemy but WHen I am writing it in mysql then I am getting error.
import pymysql
from functools import wraps
import jwt
import uuid
import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from app import app
from config import mysql
from flask import jsonify
from flask import flash, request
app.config['SECRET_KEY']='confidential'
def token_required(f):
#wraps(f)
def decorated(*args,**kwargs):
token= None
if 'x-acess-token' in request.headers:
token=request.headers['x-acess-token']
if not token:
return jsonify("token not found")
try:
data=jwt.decode(token,app.config['SECRET_KEY'])
conn=mysql.connect()
cursor=conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from hireme_emp where id=%s',data['id'])
current_user=cursor.fetchone()
except:
return jsonify('invalid token')
finally:
cursor.close()
conn.close()
return f(current_user,*args,**kwargs)
return decorated
#-----------------------------------------------
app.route('/api/view/addmin')
#token_required
def view_addmin(current_user):
try:
conn=mysql.connect()
cursor=conn.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT * FROM hireme_emp WHERE admin=1")
rows=cursor.fetchall()
resp=jsonify(rows)
resp.status_code=200
return resp
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
This is the code when I am running this endpoint without token then it is giving "token not found" message but when I send token it is displaying this error i.e (
ERROR :line 30, in decorated
cursor.close()
UnboundLocalError: local variable 'cursor' referenced before assignment
127.0.0.1 - - [23/Jul/2021 01:08:53] "GET /api/view/addmin HTTP/1.1" 500 -.
Actually below code performs same job using SQLAlchemy and is working .I am just trying to rewrite this code using pure mysql but i am not understanding where i am getting wrong. Thanks in advance for helping
def token_required(f):
#wraps(f)
def decorated(*args, **kwargs):
token = None
if 'x-access-token' in request.headers:
token = request.headers['x-access-token']
if not token:
return jsonify({'message' : 'Token is missing!'}), 401
try:
data = jwt.decode(token, app.config['SECRET_KEY'])
current_user = User.query.filter_by(public_id=data['public_id']).first()
except:
return jsonify({'message' : 'Token is invalid!'}), 401
return f(current_user, *args, **kwargs)
return decorated
define conn and cursor before you start the try catch
Further your working code shows you using public_id not id
I also change the code cursor.execute to tuples
def token_required(f):
#wraps(f)
def decorated(*args,**kwargs):
token= None
if 'x-acess-token' in request.headers:
token=request.headers['x-acess-token']
if not token:
return jsonify("token not found")
conn=mysql.connect()
cursor=conn.cursor(pymysql.cursors.DictCursor)
try:
data=jwt.decode(token,app.config['SECRET_KEY'])
cursor.execute('select * from hireme_emp where id=%s LIMIT 1',(data['public_id'],))
current_user=cursor.fetchone()
except:
return jsonify('invalid token')
finally:
cursor.close()
conn.close()
return f(current_user,*args,**kwargs)
return decorated
I am following a tutorial from codeenterpreneur. I am trying to return data defined in the tweet_list_view funtion but somehow I got a TypeError. This is code:
def tweet_list_view(request, tweet_id, *args, **kwargs):
'''
rest API
consume by javascripts or swift ios/Android
return json data
'''
qs = Tweet.objects.all()
tweet_list = [{'id': x.id, 'content': x.content} for x in qs]
data = {
"response": tweet_list,
}
return JsonResponse(data)
This is the error I am getting
TypeError at /tweets/
tweet_list_view() missing 1 required positional argument: 'tweet_id'
Update:
I want to check a JSON document on his structure. I created a JSR223 Assertion with language groovy. My code to check the JSON structure looks like this:
import groovy.json.*;
import org.apache.jmeter.samplers;
def response = prev.getResponseDataAsString();
log.info("Response" + response);
def json = new JsonSlurper().parseText(response);
//tests
def query = json.query;
assert query instanceof String;
def totalResults = json.totalResults;
assert query instanceof Integer;
def from = json.from;
assert from instanceof Integer;
def to = json.to;
assert to instanceof Integer;
assertionResult = new AssertionResult("Assertion failed! See log file.");
assertionResult.setError(true);
assertionResult.setFailureMessage(e.toString());
The validation in the JMeter logfile works great.
But in my View Result Tree, i got the following error message:
Assertion error: true
Assertion failure: false
Assertion failure message: javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script27.groovy: 2: unable to resolve class org.apache.jmeter.samplers
# line 2, column 1.
import org.apache.jmeter.samplers;
^
Script27.groovy: 21: unable to resolve class AssertionResult
# line 21, column 19.
assertionResult = new AssertionResult("Assertion failed! See log file.");
^
2 errors
I want to see if the test result is successful or not.
How to fix this issue?
Don't instantiate AssertionResult class, it is pre-defined
Don't use Groovy assert keyword, it won't fail the parent sampler as expected, refer below example simple code
if (1 != 2) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage("1 is not equal to 2")
}
once you get it working like below:
you can start modifying your tests as required
See How to Use JMeter Assertions in Three Easy Steps guide to learn more about using assertions in JMeter tests.
I have a function, that should do report, if test function success.
But, I don't want to do report, if there is an Exception inside test function.
I try to use pytest.fixture, pytest.yield_fixture, but all of them always call finalizers. How can I understand, that Exception had been raised in test function?
test.py StatisticClass: start
FStatisticClass: stop
finalizer
contest of test.py:
#pytest.mark.usefixtures("statistic_maker")
def test_dummy():
raise Exception()
content of conftest.py:
class StatisticClass():
def __init__(self, req):
self.req = req
pass
def start(self):
print "StatisticClass: start"
def stop(self):
print "StatisticClass: stop"
def if_not_exception(self):
"""
I don't want to call this if Exception inside yield.
Maybe, there is any info in request object?
"""
print "finalizer"
#pytest.yield_fixture(scope="function")
def statistic_maker(request):
ds = StatisticClass(request)
ds.start()
request.addfinalizer(ds.if_not_exception)
yield
ds.stop()
P.S. I can't use decorator because, I use fixture.
while running this script i am getting the following error...
ERROR: getTest failed. No JSON object could be decoded
My code is:
import json
import urllib
class test:
def getTest(self):
try:
url = 'http://www.exapmle.com/id/123456/'
json_ = urllib.urlopen(url).read()
self.id = json.loads(json_)
print self.id
except Exception, e:
print "ERROR: getTest failed. %s" % e
if __name__ == "__main__":
ti = test()
ti.getTest()
while opening this url "http://www.exapmle.com/id/123456/" in browser i am getting json format data, but why it is throwing an error?
Print the json_ before calling json.loads(). If there is in an error in your url, urllib does not necessarily throw an exception, it might just retrieve some error page (like with the provided url), that is not valid json.