empty end-selector value crashes annotation merge

Issue #39 resolved
Craig Berry created an issue

Selecting a word and the space after it and performing a join operation creates an annotation where the end-selector value in the range specification is empty. Like this:

       <annotation-target source="SHC-159-A20951" version="">
           <target-selector type="RangeSelector">
               <start-selector type="IdSelector" value="A20951-032-a-2810"/>
               <end-selector type="IdSelector" value=""/>
           </target-selector>
       </annotation-target>

Nothing particularly evil happens at that point, but then when that annotation is approved, there is a merge operation that fails because of the empty value. Like so:

500Merging error. err:XPTY0004: It is a type error if, during the static analysis phase, an expression is found to have a static type that is not appropriate for the context in which the expression occurs, or during the dynamic evaluation phase, the dynamic type of a value does not match a required type as specified by the matching rules in 2.5.4 SequenceType Matching. checking function parameter 1 in call map:entry(untyped-value-check[xs:anyAtomicType, $lca], $annotation): XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: map:entry($key as xs:anyAtomicType, $value as item()*) map. Expected cardinality: exactly one, got 0.

The good news is there are multiple points where we can intervene to prevent this from happening. When we get rid of the <c> elements it may become harder to select a "range" that is only one word. There should also be some sort of validation checks done at the time the annotation pane is initially populated and at the time an annotation is saved. If there aren't we need to add them, and if there are, we need to add a specific check for a missing range value. The same check ought to be done at approval time so it is impossible to approve an invalid annotation. And finally, the merge operation should be more robust so it doesn't blow up when it fails to merge.

In the short term, we'll need to find and fix the problem if it turns up again, but now that we know what we're looking for that's much easier. The following query will find any annotation item that has an empty end-selector value:

xquery version "3.1";
(: Find ranges with empty end-selector values :)
let $source := '/db/apps/shctexts/data/annotations'
return 
   for $doc in collection($source)
       for $anno in $doc/annotation-list/annotation-item
           for $emptyrange in $anno/annotation-target/target-selector[@type='RangeSelector']/end-selector[@value='']
           return 
               $anno

Comments (2)

  1. Craig Berry reporter

    I'm leaving #46 open as there should still be some client-side validation, but I'm considering this one resolved by:

    commit 61afb0144393af9bad262dc672fd2e1c85a5bb58
    Author: Craig A. Berry <craigberry@mac.com>
    Date:   Sun Nov 25 09:36:12 2018 -0600
    
        Validate annotation targets before storing.
    
        The client occasionally submits an annotation with auto-generated
        word IDs rather than real ones.  The client should be fixed to do
        its own validation, but in the meantime, validate the word IDs in
        the server and reject annotations that do not validate.  This will
        hopefully avoid various kinds of crashes that occur when merging
        non-existent words into the text.
    
  2. Log in to comment