Search code examples
xpagesxpages-ssjs

XPages SSJS Code giving error "One or more of the source document's attachment are missing"


This line

publishedDoc.save(true, false, true);

causes the above stated error once in a while, on documents saved on the web where inline images where added via CKEditor. I can't pinpoint the circumstances that causes this error, so any hints or comments are greatly appreciated.

Here is a bit more code, so you get the context of that call:

function postSavePage(doc) {
    if(doc.getItemValueString("status")=="To Be Published" || doc.getItemValueString("status")=="Save as Current Version" ) {
        var saveAsCurrent = doc.getItemValueString("status")=="Save as Current Version";
        var publishedDoc:NotesDocument = getCurrentlyPublishedDoc(doc);

        if(!publishedDoc) {
            publishedDoc = doc;
            publishedDoc.replaceItemValue("status", "Published");
            PublishedDoc.replaceItemValue("VERNUMBER", 1);
        } else {
            //******
            //copy draft to temp doc 
            var tmpDoc:NotesDocument = database.createDocument();
            doc.copyAllItems(tmpDoc, true);

            //copy published to draft (for archiving)
            publishedDoc.copyAllItems(doc, true);
            if(saveAsCurrent) {
                doc.replaceItemValue("status", "Archive (Saved As Current)");
            } else {
                doc.replaceItemValue("status", "Archive");  
            }

            //copy temp (newly published) to published doc
            tmpDoc.copyAllItems(publishedDoc, true);

            //Make sure we set the version number if saved as current version
            if(saveAsCurrent){
                publishedDoc.replaceItemValue("VERNUMBER", doc.getItemValueInteger("VERNUMBER"));
            }

            publishedDoc.replaceItemValue("status", "Published");
            updateRevisionData(doc);
            if(!saveAsCurrent) { 
                setVersion(doc);
            }

            //save docs
            doc.save(true, false, true);
            publishedDoc.save(true, false, true);
        }
    }
}

Basically, this code manages verioning in a CMS-type application. Since many doc links are already present in existing content, I need to keep the UNID of the published document. That explains the nice little dance between the published doc, the temp doc and the doc, which is the draft: Draft content goes to the published version, published version goes to thte archives.

I have persistence set to "keep pages on disk" and persistence mode to "Entire page content". Not sure it makes a difference though...

Any clues? :D


Solution

  • Wrong event. If you want to amend document data when writing back to disk use QuerySave and don't do a document.save() on the current document.

    So you might need to split your code.

    Background: XPages uploads attachments (inline images are attachments) to a temp location and keeps track of them. When you save they are added into the note and discarded. The pointer to the temp files is only reset after the event chain (QuerySave, actual write to disk, PostSave). So by trying to save again you point to files that are gone.

    Btw. Saving the current document (again) in a PostSave (or for that matter: premature save in QuerySave) is a popular Anti-pattern in Notes development