Skip to content

CouchDB replication pull handlers fails on deleted document when schema validation is enabled. #7444

@alex-zywicki

Description

@alex-zywicki

I have an RxDB setup to live replication from CouchDB, when a document is deleted from couch an error occurs that is reported by the replication states error$ subject.

When a document is deleted in CouchDB a simple stub is returned

{
  "_id": "...",
  "_rev": "...",
  "_deleted": true
}

this is then forwarded along the replication chain and seems to be hitting the Ajv validator plugin I have enabled and is failing with a validation error saying that I am missing required fields.

This is the error message (I've omitted parts to keep it short and to remove potentially sensitive info)
My schema requires several top level required fields including the data_type the error is referring to.

Err:  RxError (RC_PULL): 

Error message: RxReplication pull handler threw an error - see .errors for more details
Error code: RC_PULL
Find out more about this error here: https://rxdb.info/errors.html?console=errors#RC_PULL 

--------------------
Parameters:
writeError: {
  "status": 422,
  "isError": true,
  "documentId": "4e87f787-3336-4df9-a603-38aafad81293",
  "writeRow": {
    "document": {
      "_id": "4e87f787-3336-4df9-a603-38aafad81293",
      "_deleted": true,
      "_meta": {
        "lwt": 1759940096305.02
      },
      "_attachments": {},
      "_rev": "2-yumvvanuif"
    },
  ...
  "validationErrors": [
    {
      "instancePath": "",
      "schemaPath": "#/required",
      "keyword": "required",
      "params": {
        "missingProperty": "data_type"
      },
      "message": "must have required property 'data_type'"
    }
  ],
  ...
}

As a temporary work around I have modified my pull handler to work around this

export function handlePull(docData: any) {
    ...

    if (docData._deleted === true) {
        docData.data_type = ""; // inject defaults into deleted data to appease the validator
        ...
    }
    ...
    
    return docData;
}

After reviewing the CouchDB replication plugin implementation I would propose a fix that looks up the deleted doc in the collection and injects the current state into the event stream with the deletion applied to it.

I believe these would be the places to do so.
https://github.com/pubkey/rxdb/blob/master/src/plugins/replication-couchdb/index.ts#L127
https://github.com/pubkey/rxdb/blob/master/src/plugins/replication-couchdb/index.ts#L322

The solution would look something like

const existing = await collection.findOne({
    selector: {
        primaryKey: change._id
    }
});

const asJson = existing.toJSON();
asjson._deleted = true;
// maybe set the rev?
return asJson;

I will likely attempt to draft a PR with a more concrete fix. I will just need to take some time to figure out how to replicate this within your test suite and create a suitable bug report unit test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions