Skip to content

Implement a typed GuildPass API transport with timeout, cancellation, and structured errors #448

Description

@Lakes41

Difficulty: Advanced
Type: Feature
Recommended labels (if available in this repo): api, backend, testing, advanced

Background

GuildPass SDK V2 currently has a minimal client foundation but no reusable HTTP transport layer. Future SDK methods should not each implement fetch, timeout handling, cancellation, JSON parsing, and error conversion independently.

This issue introduces a standalone transport primitive that higher-level SDK methods can reuse later.

Problem

The SDK currently lacks a single typed transport abstraction for communicating with GuildPass Core.

Without one, future client methods may behave inconsistently around timeouts, non-2xx responses, aborted requests, malformed JSON, and network failures.

Expected Outcome

Implement a reusable HTTP transport module based on the standard Fetch API that performs requests and converts failures into stable typed SDK errors.

Suggested Implementation

Create a transport API conceptually similar to:

interface TransportRequest {
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
  path: string;
  headers?: Record<string, string>;
  body?: unknown;
  signal?: AbortSignal;
  timeoutMs?: number;
}

The transport should:

  • use the global Fetch API rather than a Node-specific HTTP client;
  • combine the configured base URL with relative request paths safely;
  • serialise JSON request bodies;
  • parse JSON responses when appropriate;
  • preserve empty successful responses;
  • reject malformed JSON responses with a typed transport error;
  • distinguish network errors from HTTP errors;
  • distinguish explicit caller cancellation from timeout cancellation;
  • support per-request timeout configuration;
  • merge caller-provided AbortSignal behaviour safely;
  • expose response status and useful metadata on HTTP failures;
  • avoid leaking response secrets or headers unnecessarily;
  • contain no GuildPass domain-specific endpoint logic.

Acceptance Criteria

  • Successful JSON requests return parsed typed data.
  • Successful empty responses are handled correctly.
  • Relative paths are resolved against the configured base URL safely.
  • JSON request bodies are serialised with the appropriate content type.
  • Non-2xx responses produce a stable typed SDK error.
  • Network failures are distinguishable from HTTP failures.
  • Timeout failures are distinguishable from caller-triggered cancellation.
  • Caller AbortSignal cancellation is supported.
  • Malformed JSON responses do not crash with an unstructured parsing error.
  • Unit tests use mocked fetch behaviour and do not require external network access.
  • Tests cover success, HTTP failure, malformed JSON, timeout, network failure, and cancellation.
  • pnpm typecheck passes.
  • pnpm build passes.
  • pnpm test passes.
  • No membership, Stellar, or access-control endpoint is implemented as part of this issue.

Likely Affected Files/Directories

src/transport/
src/errors/
src/types/
tests/

Independence Requirement

This issue must be implementable from the current main branch without depending on any other open SDK issue.

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

    GrantFox OSSGrantFox Open Source Sponsorship program tagMaybe RewardedIssue may qualify for a reward upon successful completion per campaign rulesThird CampaignOfficial FWC26 campaign issue — eligible for campaign scoring and rewardsadvancedAdvanced difficulty tasks requiring significant domain knowledge and implementation effortapiAPI routes, request handling, response contracts, and service integration workbackendBackend services, application logic, persistence integration, and server-side functionalitytestingAutomated testing, integration testing, test infrastructure, and verification work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions