Skip to content

[BUG] A missing message package is reported as a gateway fault, or as no data at all #614

Description

@bburda

Bug report

Steps to reproduce

  1. Run a gateway whose image does not contain a message package that is present in the ROS graph,
    for example nav2_msgs.
  2. GET /api/v1/apps/<id>/data/<url-encoded topic of that type>.
  3. Execute an operation backed by a service or action whose type comes from a package the gateway
    image does not have.
  4. Separately, set up a case where the package resolves when the subscription is created, but its
    introspection library is missing.

Expected behavior

"This type is not installed here" is a different answer from "the gateway failed". A client that
walks the endpoint tree can tell them apart, and the tree does not advertise a resource it can
never serve.

Actual behavior

Steps 2 and 3 return 500, the same on the owning gateway and through an aggregator:

{"error_code": "vendor-error",
 "message": "package 'nav2_msgs' not found",
 "parameters": {"entity_id": "<app-id>", "topic_name": "/<topic>"},
 "vendor_code": "x-medkit-subscribe-failed"}

The gateway is working correctly here. The type is simply not installed. As a 500 it cannot be
told apart from a gateway fault by any client walking the endpoints.

Step 4 returns 200 OK with x-medkit.status = "metadata_only" and an empty type_info.

The metadata_only fallback itself is deliberate and useful. #52 added it so that a topic which
is not currently publishing returns its type, schema and default-value template instead of a 404.
The point of the fallback is that the client still gets the schema. This is the one case where
there is no schema to give, because the type cannot be introspected. The response then looks the
same as an idle topic and carries nothing the client can use. A consumer cannot tell "no
publisher right now" from "this gateway can never decode this type".

Environment

  • ros2_medkit version: main (a268379), gateway vendor_info.version 0.6.0, SOVD API 1.0.0
  • ROS 2 distro: Jazzy
  • OS: Ubuntu 24.04

Additional information

The 500 comes from src/data/ros2_topic_data_provider.cpp:380-383, which wraps any failure to
create the subscription as ErrorInfo{ERR_X_MEDKIT_SUBSCRIBE_FAILED, ..., 500, ...}.

The exception type is already lost by then. Ros2SubscriptionExecutor::run_sync
(include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp:344) catches
const std::exception & and stores ex.what() as a plain std::string. So
ament_index_cpp::PackageNotFoundError and a real rcl fault arrive at the handler as the same
thing. Telling them apart in the handler needs the type kept at that boundary.

The 200 path is src/data/ros2_topic_data_provider.cpp:502-517. TypeNotFoundError from the
serializer is caught, logged once per type, and sets result.has_data = false. The empty
type_info comes from src/ros2_medkit_serialization/src/type_introspection.cpp:73-86:
get_type_schema throws for a type that cannot be resolved, the schema falls back to an empty
object, and the result is deliberately not cached because resolution may be temporary. So the
same code that leaves the schema empty already knows the type could not be resolved.

Operations collapse the same way, to 500 with x-medkit-ros2-service-unavailable and
x-medkit-ros2-action-unavailable (src/http/handlers/operation_handlers.cpp:705-707,
:675-677).

Two things that already exist and are not used:

  • ERR_X_MEDKIT_ROS2_TYPE_INTROSPECTION_FAILED is declared at
    include/ros2_medkit_gateway/core/http/error_codes.hpp:91 and has no other reference in the
    tree.
  • 415 does not appear anywhere in the repository. In the data path, 501 is used only for
    data-categories and data-groups.

Capabilities and the per-topic list are not filtered by whether a type can be resolved. The app
and component capability vectors are hard-coded
(src/http/handlers/discovery_handlers.cpp:1112-1114, :741-744), and the per-topic list logs a
DEBUG line and lists the item anyway when introspection fails
(src/http/handlers/data_handlers.cpp:106-109). So /data advertises resources the gateway
cannot serve. That part overlaps #515.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions