Skip to content

wire::encode's glaze-write error branch is unreachable without a glaze fault-injection seam #96

Description

@Yaraslaut

Problem

wire::encode() (include/morph/core/wire.hpp) wraps glz::write<detail::EscapingWriteOpts{}>(env, out) and throws std::runtime_error if it returns a non-none error code:

inline std::string encode(const Envelope& env) {
    std::string out;
    if (auto errCode = glz::write<detail::EscapingWriteOpts{}>(env, out)) {
        throw std::runtime_error("envelope encode failed: " + glz::format_error(errCode, out));
    }
    return out;
}

The doc comment on encode already says the throw path "should never happen for valid input," and that appears to be exactly true for Envelope's current shape: walking glaze 7.4's json/write.hpp, every site that actually sets a non-none ctx.error during a write is one of invalid_partial_key / unknown_key (only reachable via glaze's partial-write-by-key-list feature, which encode does not use) or invalid_variant_object (only reachable through a std::variant member, and Envelope has none — every field is a plain scalar, std::string, or session::Context, none of which are variants).

Confirmed real impact

Branch-coverage sweep flagged include/morph/core/wire.hpp:420's if (auto errCode = ...) as 1/2 arms covered — the error (true) arm never executes anywhere in the test suite (tests/test_wire_hardening.cpp and friends). Investigating this gap (rather than writing a test to force it) confirmed there is currently no way to construct an in-memory Envelope value that drives glz::write to a non-none error code, because none of glaze's actual write-failure trigger sites apply to this struct's shape.

What's needed

A fault-injection seam in glaze's writer — something a test can use to force a glz::write call to fail deterministically for an otherwise-valid, non-variant, non-partial-write struct (e.g. a documented way to make write<Opts> return a synthetic error code for testing, or an error_code reachable from a plain reflected struct without opting into partial-write/variant features). Without that, this repo's own test suite cannot exercise encode's throw path without either (a) changing Envelope's shape purely to make a test possible, which would be a design compromise for testability's sake, or (b) mocking/forking glaze locally, which this repo does not do for any other dependency.

Suggested resolution

Either:

  • Document (in glaze's own README/docs) which specific struct shapes and options combinations can actually produce a write-time error, so downstream users can tell provably-unreachable throw paths from real ones without reading write.hpp line by line, or
  • Expose a minimal fault-injection hook (even a debug-only one) that lets a test force write's internal ctx.error to a chosen value for a single call, so wrapper code like morph::wire::encode's error-handling branch can be covered by a real unit test instead of staying permanently unreachable dead code from a coverage-tool's point of view.

Where this was found

include/morph/core/wire.hpp:420, morph::wire::encode. See docs/spec/core/wire.md, "Encode and decode".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions