backend icon indicating copy to clipboard operation
backend copied to clipboard

Proposal: Refactor API Error Responses into Structured Format (Current Format Is Hard to Parse and Work With)

Open brootle opened this issue 8 months ago • 2 comments

Hi team,

I’ve been working extensively with the DeSo API, and I’d like to raise a serious issue regarding the format of error responses. Right now, most errors are returned as long, concatenated strings that are difficult to parse, debug, or show to end-users in any meaningful way.

Here’s a real-world example:

{
  "error": "SubmitTransaction: Problem processing transaction: VerifyAndBroadcastTransaction: Problem broadcasting txn: BroadcastTransaction: Transaction 170c05780427f5867ebf3e6340380413379efa10e6a8b0f70dba7e1ed33378b7 was not validated due to error: TryConnectTransaction: Problem connecting txn on copy view: ConnectTransaction: : _connectSubmitPost: : _connectBasicTransferWithExtraSpend : _connectBasicTransferWithExtraSpend Problem verifying txn signature: : Derived key EITHER deactivated or block height expired. Deactivation status: 1, Expiration block height: 1348722, Current block height: 16701403: RuleErrorDerivedKeyNotAuthorized"
}

The actual root cause of the failure—Derived key either deactivated or block height expired—is deeply buried in this message. As a developer, I have to either display this entire verbose error to the user (which makes no sense) or try to extract the actionable part with brittle string parsing.

✅ Suggested Solution

Please consider refactoring error responses into structured JSON objects like this:

{
  "error": {
    "code": "ERR_DERIVED_KEY_EXPIRED",
    "message": "Derived key either deactivated or block height expired.",
    "details": {
      "deactivation_status": 1,
      "expiration_block_height": 1348722,
      "current_block_height": 16701403
    },
    "stack": [
      "SubmitTransaction",
      "VerifyAndBroadcastTransaction",
      "BroadcastTransaction",
      "TryConnectTransaction",
      "_connectSubmitPost",
      "_connectBasicTransferWithExtraSpend"
    ]
  }
}

This would make it much easier to:

  • Display clean and friendly error messages in the UI.
  • Handle specific error types programmatically.
  • Log and diagnose issues faster.
  • Build better developer tooling around the API.
  • Localize or document error types consistently.

⚙️ Optional: Transitional Support

To avoid breaking current consumers, a transitional format could include both:

{
  "legacy_error": "SubmitTransaction: Problem processing transaction: ...",
  "error": { ...structured version... }
}

🧠 Why This Matters

Structured errors are standard practice in mature APIs like Stripe, GitHub, and Twilio. They’re critical for developer experience, debugging, and end-user messaging. The current format makes error handling brittle and hard to scale as app complexity grows.

📣 Next Steps

If this aligns with your roadmap, I’d be happy to turn it into a formal DIP and open a proposal in deso-protocol/dips to standardize structured error formats across the ecosystem.

Thanks for considering this—this change would significantly improve developer experience across all apps built on DeSo.

brootle avatar May 09 '25 07:05 brootle

Couldn't agree more.

But this is still breaking for existing apps:

{
  "legacy_error": "SubmitTransaction: Problem processing transaction: ...",
  "error": { ...structured version... }
}

I think we should keep "error" as the legacy and then "error_structured" (or any better name) as the new structured error

erwin-willems avatar May 09 '25 07:05 erwin-willems

Absolutely!

Or a defined(!) list of error codes that frontends can use for e.g. translation purposes.

E.g. building on @erwin-willems's suggestion

{
  "error": "SubmitTransaction: Problem processing transaction: ...",
  "errorCode": "XYZ",
  "errorVerbose": {
      "code": "ERR_DERIVED_KEY_EXPIRED",
        "message": "Derived key either deactivated or block height expired.",
        "details": {
          "deactivation_status": 1,
          "expiration_block_height": 1348722,
          "current_block_height": 16701403
        },
        "stack": [
          "SubmitTransaction",
          "VerifyAndBroadcastTransaction",
          "BroadcastTransaction",
          "TryConnectTransaction",
          "_connectSubmitPost",
          "_connectBasicTransferWithExtraSpend"
        ]
    }
}

Then apps could use their own translation tables for different languages etc (could be another community-contributed / centrally available library).

StarGeezerPhil avatar May 09 '25 14:05 StarGeezerPhil