Exception in sync function

My app has stopped syncing because the SG is returning a 500 500 Exception in JS sync function. I can see this in the SG logs:

2016-06-25T18:18:01.080+01:00 CRUD+: Invoking sync on doc "-11qdQweNbfgmHA_bIf1_4j" rev 2-070f7f82f5a61bd0fbc7a685a7c3739e
2016-06-25T18:18:01.080+01:00 CRUD+: No old revision "-11qdQweNbfgmHA_bIf1_4j" / "1-050d5372f2de225977483623f2dd40b6"
2016-06-25T18:18:01.080+01:00 WARNING: Sync fn exception: TypeError; doc = map[_rev:2-070f7f82f5a61bd0fbc7a685a7c3739e _deleted:%!s(bool=true) _revisions:map[ids:[070f7f82f5a61bd0fbc7a685a7c3739e 050d5372f2de225977483623f2dd40b6] start:%!s(float64=2)] _id:-11qdQweNbfgmHA_bIf1_4j] -- db.(*Database).getChannelsAndAccess() at crud.go:795
2016-06-25T18:18:01.080+01:00   BulkDocs: Doc "-11qdQweNbfgmHA_bIf1_4j" --> 500 Exception in JS sync function (500 Exception in JS sync function)

The client has a conflict on it, but I don’t understand the nature of the conflict. It looks like the document is in conflict with itself. The is the output of a view that tracks conflicts:

The conflicting revision is the same revision as the document revision. What does this mean?

The view looks like this:

function (doc) {
        if (doc._conflicts) {
          emit(doc._conflicts, doc);
        }
      }

Can you tell where exactly your sync function is throwing the TypeError? From the SG logs the document properties look reasonable.

Thanks the problem - I’ve sent you every error message I could find. All it says in the SG logs is what I pasted, essentially this:

Sync fn exception: TypeError; doc = map[_rev:2-070f7f82f5a61bd0fbc7a685a7c3739e _deleted:%!s(bool=true) _revisions:map[ids:[070f7f82f5a61bd0fbc7a685a7c3739e 050d5372f2de225977483623f2dd40b6] start:%!s(float64=2)] _id:-11qdQweNbfgmHA_bIf1_4j] -- db.(*Database).getChannelsAndAccess() at crud.go:795

Are you able to share your Sync Function (or a sanitized version of it)?

Here it is: https://raw.githubusercontent.com/npomfret/datr/36194f95d09e9d9b6b5a57fd1b1302cd51ef766d/app/sync-function.js

@nick-couchbase

I dont know if this is the reason you are seeing a JS Exception, but if the first revision of a doc that SG receives is deleted, the sync function will attempt to build channels from oldDoc which is null.

curl -X PUT http://localhost:4985/db/doc7 -H "Content-Type: application/json" -d '{"type":"chat-message", "owners":"crashtest","_deleted":"true"}'
{"error":"Internal Server Error","reason":"Exception in JS sync function"}

thanks for the reply. are you saying that someone edited a deleted document?

@nick-couchbase

I can’t say that the error flow I found is the one that caused your issue, you could add debug logging into your sync function and try to re-sync from the client with the document you identified above. That would allow you to confirm the flow that the particular document takes through the sync function.

e.g.

if(newDoc._deleted) {
        console.log("INFO: newDoc IS _deleted");
        channels = getChannelsFrom(oldDoc);
    } else {
        channels = getChannelsFrom(newDoc);
    }

Just to add to what Andy’s saying - the Javascript error is happening when you call
channels = getChannelsFrom(oldDoc); while oldDoc is null.

This doesn’t look like an edit on a deleted doc. Based on the doc output included in the log, it looks like revision 2 of doc
-11qdQweNbfgmHA_bIf1_4j is a tombstone. There are probably a few valid reasons why Sync Gateway might not have the parent revision - I think the key is that your Sync Function should handle this scenario.

I thought oldDoc being null meant this is a new document, which has no old doc? Have I misunderstood?

oldDoc is the body of the revision’s nearest ancestor. If Sync Gateway doesn’t have the document body for an ancestor, oldDoc will be null.

This is obviously the case for new documents, but there are other scenarios where Sync Gateway won’t have access to the ancestor body. Some of these include:

  1. The new revision is a conflicting revision, branching from an older revision that’s no longer available to Sync Gateway (Sync Gateway only retains bodies for non-tombstoned leaf revisions).
  2. This is a new document to Sync Gateway, but there have been multiple revisions made by the client that are being pushed.