cloudant / python-cloudant

A Python library for Cloudant and CouchDB
Apache License 2.0
163 stars 55 forks source link

Getting HTTPError instead of KeyError #506

Closed paketep closed 3 years ago

paketep commented 3 years ago

Bug Description

When I work with a document that is deleted in the background by another process, I expect to get a KeyError either when I access it as a dictionary, or when I do fetch. I get a 404 HTTPError.

What's worse, if I do id in DB, it still says True

1. Steps to reproduce and the simplest code sample possible to demonstrate the issue

try:
    ticket = mydb['testdocument']
    ticket.fetch()
except KeyError:
    print("Document was deleted")

# I delete the document directly in the database

try:
    'testdocument' in mydb  # returns True
    ticket = mydb['testdocument']  # executes correctly
    ticket.fetch()  # raises the HttpError
except KeyError:
    print("Nope")

2. What you expected to happen

I expected a KeyError raised at least when I did fetch. I expected 'testdocument' in mydb to return False after I deleted the document (and before doing fetch)

3. What actually happened

HttpError, 404 status code

Environment details

I have quite a few KeyErrors that I expect raised if the doc doesn't exist, regardless of whether I've fetched the document before or not. I'd hate to have to change all of those, please tell me that I'm doing something wrong.

ricellis commented 3 years ago

Calling fetch explicitly asks the remote server for the document - so the HttpError 404 is the expected response as the document is now deleted on the server.

The statements:

'testdocument' in mydb  # returns True
ticket = mydb['testdocument']  # executes correctly

are correct even after the remote deletion occurs because they are operating on the local dict which still contains a previous revision of the document (i.e. the local cache knows nothing of the remote update/deletion until fetch is called).

It appears that after the fetch [of the deleted remote revision] is called the local cache still retains the undeleted revision. Personally I think that behaviour is not correct; more likely it should follow similar behaviour to the delete function. However, given the deprecation timeline for this library I don't think we'll be making changes to that behaviour at this stage.

If you find the local cache behaviour awkward it is worth noting that our replacement library ibmcloudant/cloudant-python-sdk does not have it.

paketep commented 3 years ago

I'll take a look at that, thanks