How to handle - AttributeError: 'NoneType' object has no attribute 'patient_id'

Viewed 2614

Looking for some guidance here. I'd like to know how to handle the exception in this question's title. Complete error posted below the code.

SOME CONTEXT: During testing - this code block below in my python script works when there's a matching patient in the DB, but throws an exception when there's there's no matching 'patient_id' found in the DB table. I'd like to be able to handle this exception somehow. Maybe i just need to rewrite my IF-NOT statement. I need to be able to account for/handle wildcard entries from the user e.g. my DB has patient_IDs '1 thru 10'. Code works fine when '1 thru 10' is entered by the user. If user enters 11 for example, i get the exception. Need to handle it somehow.

Constructive feedback is appreciated.

def delete_patient():
    if not request.form['pid']:
        flash("Field cannot be empty when deleting a Patient.", "orange")
#function takes mandated user input via request form
    else:
        trashXX = request.form['pid']
        trash02 = silver.query.filter_by(patient_id=request.form['pid']).all()
        for i in trash02:
            divo.session.delete(i)
            divo.session.commit()
        trash03 = gold.query.filter_by(patient_id=trashXX).first()
        divo.session.delete(trash03)
        divo.session.commit()
        flash("Patient Deleted Successfully", "green")
    return redirect(url_for('show_patients'))
#function uses mandated user input as a a filter to locate patient (and records) in DB
#function locates a valid patient in DB, and proceeds to delete patient records first, and patient second.

COMPLETE EXCEPTION:

AttributeError: 'NoneType' object has no attribute 'patient_id'
Traceback (most recent call last)

    File "C:\Python39\Lib\site-packages\flask\app.py", line 2464, in __call__

    return self.wsgi_app(environ, start_response)

    File "C:\Python39\Lib\site-packages\flask\app.py", line 2450, in wsgi_app

    response = self.handle_exception(e)

    File "C:\Python39\Lib\site-packages\flask\app.py", line 1867, in handle_exception

    reraise(exc_type, exc_value, tb)

    File "C:\Python39\Lib\site-packages\flask\_compat.py", line 39, in reraise

    raise value

    File "C:\Python39\Lib\site-packages\flask\app.py", line 2447, in wsgi_app

    response = self.full_dispatch_request()

    File "C:\Python39\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request

    rv = self.handle_user_exception(e)

    File "C:\Python39\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception

    reraise(exc_type, exc_value, tb)

    File "C:\Python39\Lib\site-packages\flask\_compat.py", line 39, in reraise

    raise value

    File "C:\Python39\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request

    rv = self.dispatch_request()

    File "C:\Python39\Lib\site-packages\flask\app.py", line 1936, in dispatch_request

    return self.view_functions[rule.endpoint](**req.view_args)

    File "<path>\tahnApp_01.py", line 226, in delete_patient

    trashXX = trash02.patient_id

    AttributeError: 'NoneType' object has no attribute 'patient_id'
1 Answers

You can use hasattr() or catch AttributeError but the Python community recommend a strategy of "it is easier to ask for forgiveness than permission", so you should look for the attribute inside a try - except block, like this:

try:
    if obj['patient_id']: # Look for attribute
        pass
except AttributeError:
    # Attribute not found, handle error
    pass

If your obj can be None, as it seems from the error (AttributeError: 'NoneType' object has no attribute 'patient_id'), it is good practice to handle the case:

if obj:
    try:
        if obj['patient_id']: # Look for attribute
            pass # Do something
    except AttributeError:
        # Attribute not found
        pass # Handle error
else:
    print('obj is None!')

You can find more info about exceptions handling here: Python docs

Your other option is to explicity look in advance if your object has the attribute using hasattr():

if obj:
    if hasattr(obj, 'property'):
        pass # Do something
    else:
        pass # Handle the missing attribute
else:
    pass: # Handle the missing object

If you want the value of the attribute with a default if it isn't there, you can use getattr():

if obj:
    a = getattr(obj, 'property', 'default value')
else:
    pass # Handle the missing object
Related