cloudant / sync-android

A JSON-based document datastore for Android applications
Apache License 2.0
267 stars 91 forks source link

Calling getAttachments() on a deleted revision throws ClassCastException #521

Closed brynh closed 7 years ago

brynh commented 7 years ago

In sync-android v2.0.0, when calling getAttachments() on a deleted revision, a ClassCastException is thrown:

java.lang.ClassCastException: java.util.HashMap cannot be cast to com.cloudant.sync.internal.common.ChangeNotifyingMap

Although one shouldn't be able to access attachments on a deleted revision, it would be much nicer if this returned null or an empty Map or a more appropriate exception.

A simple example demonstrating this issue is:

File path = getApplicationContext().getDir("documentstores", Context.MODE_PRIVATE);

try {
    DocumentStore ds = DocumentStore.getInstance(new File(path, "my_document_store"));

    DocumentRevision revision = new DocumentRevision();
    Map<String, Object> body = new HashMap<String, Object>();
    body.put("animal", "cat");
    revision.setBody(DocumentBodyFactory.create(body));

    DocumentRevision saved = ds.database().create(revision);
    Map<String, Attachment> attachments = saved.getAttachments(); // <<< This works.

    DocumentRevision deleted = ds.database().delete(saved);
    attachments = deleted.getAttachments(); // <<< This throws a ClassCastException.

} catch (Exception e) {
    e.printStackTrace();
}

Relevant stack trace:

java.lang.ClassCastException: java.util.HashMap cannot be cast to com.cloudant.sync.internal.common.ChangeNotifyingMap
at com.cloudant.sync.internal.documentstore.InternalDocumentRevision.getAttachments(InternalDocumentRevision.java:214)
at com.cloudant.sync.internal.documentstore.InternalDocumentRevision.getAttachments(InternalDocumentRevision.java:32)
...
ricellis commented 7 years ago

Fixed by #522