replyErrBytes method
Sends an error reply to this query with a ZBytes payload.
The payload is consumed by this call (ownership transferred to zenoh).
Optionally specify an encoding for the payload. Error replies carry a
payload + encoding ONLY -- there is no attachment parameter (zenoh-c's
z_query_reply_err_options_t has no attachment field).
Throws StateError if the query has been disposed. Throws ZenohException if the reply fails.
Implementation
void replyErrBytes(ZBytes payload, {Encoding? encoding}) {
// PRE-move early-return guard: a disposed query throws StateError here,
// BEFORE any z_bytes_move, so the caller retains ownership of payload and
// we must NOT mark it consumed on this path (mirrors replyBytes).
_ensureNotDisposed();
// Two INDEPENDENT length-carried channels (R-2), from the RAW pair (R-3a).
final (mime, schema) = encoding != null
? encodingWireChannels(encoding)
: (null, null);
final encodingBuf = allocLengthCarriedUtf8(mime);
final schemaBuf = allocLengthCarriedUtf8(schema);
try {
final rc = bindings.zd_query_reply_err(
Pointer.fromAddress(_handle).cast(),
payload.nativePtr.cast(),
encodingBuf.ptr,
encodingBuf.len,
schemaBuf.ptr,
schemaBuf.len,
);
// Mark the payload ZBytes consumed UNCONDITIONALLY: once we reach this
// FFI call the pre-move guard above has passed, so zd_query_reply_err has
// moved the payload into zenoh-c regardless of the return code (its
// encoding-error path drops the already-moved bytes). Marking before the
// rc-throw prevents a later use-after-move. The encoding is a MIME string
// (not a caller-owned ZBytes), so it needs no Dart-side markConsumed.
payload.markConsumed();
if (rc != 0) {
throw ZenohException('Failed to send error reply to query', rc);
}
} finally {
if (encodingBuf.ptr != nullptr) calloc.free(encodingBuf.ptr);
if (schemaBuf.ptr != nullptr) calloc.free(schemaBuf.ptr);
}
}