The edge iterator is more complicated than other iterators because it can dynamically swap edge objects back and forth from disk storage. The vertex message iterator is simpler because there is only one such iterator and the vertex messages are discarded when the iterator moves past them. As such, the vertex message iterator does not need a close() method.
When the graph function returns control to the runner (that is, when returning from initializeVertex, operateOnVertex, or emitFinalRows), the edge iterator on that vertex should be automatically closed (if any). The graph function could store an edge iterator off to the side (for example, in a global variable) and then try to access it after the graph processing has moved on to another vertex. It should appear to be closed in that case.
You could also store a pointer to a VertexState, and try to open an edge iterator for one vertex while the graph processing is positioned on a different vertex. This should not be done.
Arguments passed to initializeVertex, operateOnVertex, emitFinalRows, or undeliverableMessagesHandler should be considered temporary objects, which are only valid within that call. This rule extends to EdgeIterators retrieved from a VertexState.