Skip to content

Stream finalization overwrites iteration errors with OK status #1434

Description

@KXHXK

Description

The shared sync and async stream wrappers overwrite an iteration failure with a successful span status during finalization.

Both wrappers catch an iteration exception, set the span to ERROR, record the exception, and re-raise it. Their finally blocks then call BaseStreamWrapper._finalize(), which unconditionally sets the same span to OK before ending it.

The final exported status can therefore report a failed provider stream as successful even though the original exception is preserved for the caller.

Minimal reproduction

from unittest.mock import Mock

from agentops.instrumentation.common.streaming import SyncStreamWrapper


def failing_stream():
    yield chunk
    raise ValueError(boom)


span = Mock()
try:
    list(SyncStreamWrapper(failing_stream(), span, lambda chunk: chunk))
except ValueError:
    pass

print([call.args[0].status_code.name for call in span.set_status.call_args_list])

Current output on main:

['ERROR', 'OK']

The async wrapper follows the same control flow.

Expected behavior

Successful streams should end with OK. Failed streams should record the original exception and end with ERROR, without a later OK status update.

Suggested fix

Let _finalize() know whether iteration completed successfully, or move the success status assignment out of unconditional finalization. Add sync and async regression assertions for the final status.

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