Skip to content

Bug report: MessageFactory.GetMessage(ProtoMessage) has no case for ProtoOAOrderListRes #36

Description

@aaronhicksuk

Bug report: MessageFactory.GetMessage(ProtoMessage) has no case for ProtoOAOrderListRes

Package: cTrader.OpenAPI.Net (also published as Spotware.OpenAPI.Net), version 1.4.4
Repository: https://github.com/spotware/OpenAPI.Net

Summary

OpenAPI.Net.Helpers.MessageFactory.GetMessage(ProtoMessage) decodes an incoming
message by switching on its numeric PayloadType to the matching typed parser. The
switch is missing a case for payload type 2176 (ProtoOAOrderListRes), so a
reply to ProtoOAOrderListReq (payload type 2175) can never be decoded into a typed
ProtoOAOrderListRes object — only the raw, untyped ProtoMessage envelope is ever
emitted to subscribers.

Any caller waiting on the typed object (e.g. via client.OfType<ProtoOAOrderListRes>(),
the pattern used throughout this library's own samples) will wait indefinitely for a
message that is never produced, even though the server has replied and the bytes are
sitting in the raw envelope the whole time.

Evidence

Decompiling OpenAPI.Net.dll 1.4.4 (MessageFactory.GetMessage(ProtoMessage)) shows
the full switch. Every other response type this app depends on is present —
ProtoOACashFlowHistoryListRes (2144), ProtoOAApplicationAuthRes (2101),
ProtoOAAccountAuthRes (2103), ProtoOAGetAccountListByAccessTokenRes (2150),
ProtoOASymbolByIdRes (2117), ProtoOADealListRes (2134) — but 2175/2176
(ProtoOAOrderListReq/Res) do not appear anywhere in it:

public static IMessage GetMessage(ProtoMessage protoMessage)
{
    ByteString payload = protoMessage.Payload;
    return (IMessage)(protoMessage.PayloadType switch
    {
        2142u => ProtoOAErrorRes.Parser.ParseFrom(payload),
        51u => ProtoHeartbeatEvent.Parser.ParseFrom(payload),
        2103u => ProtoOAAccountAuthRes.Parser.ParseFrom(payload),
        2101u => ProtoOAApplicationAuthRes.Parser.ParseFrom(payload),
        2148u => ProtoOAClientDisconnectEvent.Parser.ParseFrom(payload),
        2134u => ProtoOADealListRes.Parser.ParseFrom(payload),
        // ... ~30 more cases ...
        2150u => ProtoOAGetAccountListByAccessTokenRes.Parser.ParseFrom(payload),
        2178u => ProtoOAGetDynamicLeverageByIDRes.Parser.ParseFrom(payload),
        _ => null,   // <-- 2176 (ProtoOAOrderListRes) falls through to here
    });
}

Impact observed

In our application, every ProtoOAOrderListReq — regardless of the requested date
range, including a week with zero trading activity — ran out a 60-second client-side
deadline waiting for ProtoOAOrderListRes, with 100% failure and almost no variance
in timing (~60.02s every time). The connection itself was healthy throughout (TCP
stayed ESTABLISHED, other request types on the same session completed normally in
milliseconds). This looked exactly like a silently-unresponsive server or an
insufficient OAuth scope, and cost significant time to rule those out before finding
the actual cause in the library itself.

Suggested fix

Add the missing case, matching the existing pattern:

2176u => ProtoOAOrderListRes.Parser.ParseFrom(payload),

Workaround (for anyone hitting this before it's fixed upstream)

Subscribe to the raw ProtoMessage envelope alongside the typed subscription, and
when a message's PayloadType matches the expected response type but the typed
object never arrives, decode it manually:

var typed = new ProtoOAOrderListRes();
typed.MergeFrom(rawMessage.Payload);

This works around any payload type missing from the library's own table, not just
this one, since it decodes directly from the raw envelope rather than relying on
MessageFactory.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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