Skip to content

[Feature] Add error state and timeout handling for asset data loading failures #69

Description

@numbers-official

Summary

When API calls fail during modal opening, the widget remains in a permanent shimmer/loading skeleton state with no error feedback, no timeout, and no way for consumers to detect the failure.

Location

File: src/modal/modal-manager.ts — Lines 47-62
File: src/asset/asset-service.ts — Lines 67-70, 89-92, 117-120

Problem

When the modal opens, ModalManager.updateModal() fires three parallel API calls (fetchAsset, hasNftProduct, fetchAssetMetadata). Each function catches all errors and silently returns undefined or false.

When fetchAsset returns undefined:

  • updateModalAsset silently bails out (line 90: if (!assetModel) return)
  • _assetLoaded never becomes true
  • The modal stays in shimmer skeleton state indefinitely

This affects:

  • Network failures (offline, DNS, timeouts)
  • API downtime (500, 503 errors)
  • Invalid nid values (404 responses)
  • Rate limiting (429 responses)

Impact

  • User experience: Users see an eternally-loading widget with no explanation and no call to action
  • Developer experience: No programmatic way to detect failure — no error event, no rejected promise, no error state property
  • Debugging: Errors only appear in console.error, invisible to end users and site operators

Suggested Implementation

  1. Add _loadError state to CaptureEyeModal:

    @state() protected _loadError = false;

    When set, render a user-friendly message (e.g., "Unable to load provenance data") instead of the shimmer skeleton.

  2. Add timeout in ModalManager.updateModal(): if fetchAsset does not resolve within 10 seconds, set the error state.

  3. Dispatch custom error event from <capture-eye>:

    this.dispatchEvent(new CustomEvent('capture-eye-error', {
        detail: { nid: this.nid, error: 'Failed to load asset data' },
        bubbles: true,
        composed: true
    }));
  4. Expose loading state property on <capture-eye> (loadingState: 'loading' | 'loaded' | 'error') for programmatic access.

  5. Optional single retry with 2-3 second backoff for transient failures.

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