A pipeline uses ncclient to lock the candidate datastore and stage an interface change on 60 IOS XE routers. Two routers return an <rpc-error> with error-tag lock-denied because another job holds the lock, one router's SSH session drops before the reply arrives, and the rest return <ok/> for the edit-config request. For each device, the pipeline must report the change as staged, delayed or unreachable without stopping the run. Which reply-reading and error-handling pattern should it use?
Select an answer to reveal the explanation.
Short Explanation
You need all three signals: an <ok/> for the edit-config reply confirms the change was accepted into the candidate datastore, a caught RPCError provides the error-tag, and a dropped session is a connection result, not a device verdict. It's easy to blur them and log a lock conflict as an outage. Only the full set lets you label each router staged, delayed or unreachable.
Full Explanation
A successful edit-config reply ending in <ok/> confirms that the change was accepted into the candidate datastore; it does not mean the change was committed to running. A successful lock reply also ends in <ok/>, but confirms only that the lock succeeded. Server-side rejections come back as <rpc-error> carrying error-tag, error-type and error-path, and ncclient can surface a single one as a catchable RPCError whose tag attribute lets you branch and treat lock-denied as contention to delay. A dropped SSH channel or a session timeout raises from the connection layer instead, so it belongs in the unreachable bucket. A pattern that reads replies but never branches on error-tag cannot separate contention from a genuine failure, a pattern that trusts the absence of an exception infers success without checking <ok/>, and a pattern that files every raised exception as a server-side error mislabels connection loss as a device fault. Practical check: hold the lock from a second session, then confirm your log prints lock-denied as delayed while a dropped link prints unreachable.