DEV Community

Archi Grant
Archi Grant

Posted on

Web3 Error Messages: Small Details That Can Make or Break an App

There's one part of frontend development that I think deserves more attention: error handling.

It's easy to spend hours polishing a dashboard, choosing the right colors, and making animations feel smooth. But what happens when an API request fails or a wallet connection doesn't work?

That's when the quality of an application becomes much more noticeable.

In Web3, this problem is especially interesting because a single user action can involve several systems: a frontend, a wallet, an RPC provider, and a blockchain network.

If something goes wrong, the user shouldn't have to guess what happened.

Not every error means the same thing

Consider a simple token swap interface.

A user clicks the swap button, but the expected result doesn't appear. Several things could have happened:

The wallet wasn't connected.

The selected network was incorrect.

The transaction was rejected by the user.

The RPC request timed out.

The transaction was submitted but hasn't been confirmed yet.

Showing the same message for all five situations creates unnecessary confusion.

A better approach is to identify the failure category and communicate what the application actually knows.

For example, a rejected wallet request should not be presented as a blockchain failure. A pending transaction shouldn't be treated as a failed transaction simply because confirmation is taking longer than expected.

These distinctions are small from a coding perspective, but important from a user perspective.

Design error states before they happen

One practical approach is to map out the possible states of an operation before implementing the interface.

For a wallet-connected application, I would start with states such as:

Disconnected — The user needs to connect a wallet.

Ready — The application has the information required to continue.

Awaiting approval — The user needs to review or approve a wallet request.

Pending — The transaction has been submitted and is awaiting confirmation.

Confirmed — The application has sufficient evidence that the transaction succeeded.

Failed — The transaction or operation has failed, and the interface can explain what is known.

The exact states depend on the application, but writing them down early helps prevent contradictory UI behavior.

It also makes frontend components easier to reason about and test.

Don't turn every problem into a generic message

Compare these two messages:

"Something went wrong. Try again."

"Your wallet request was rejected. No transaction was submitted by this request."

The second message is more useful when the application can reliably establish that the request was rejected before submission.

The important qualification is that the interface must not claim more than it knows. A network timeout, for example, doesn't necessarily prove that a transaction wasn't submitted.

When the outcome is uncertain, the application should communicate that uncertainty and help the user check the transaction status before trying again.

This is especially important when repeating an action could produce an unintended duplicate transaction.

A few implementation principles

When building error handling into a Web3 frontend, I'd focus on four things.

  1. Separate technical errors from user-facing messages.

Keep the underlying error information available for debugging, but translate it into clear language for the interface. Avoid exposing private data, internal credentials, or unnecessary implementation details.

  1. Give users a safe next step.

Depending on the situation, that might mean reconnecting a wallet, checking the selected network, reviewing transaction details, or waiting for confirmation.

  1. Handle asynchronous states explicitly.

Loading, pending, success, and failure should be distinct states rather than a collection of loosely connected UI flags.

  1. Test failure scenarios.

Test rejected wallet requests, unavailable RPC endpoints, malformed responses, and delayed confirmations. A successful demo doesn't tell you how the interface behaves under pressure.

Why this matters beyond crypto

These principles apply to ordinary web applications too.

A payment form, an upload workflow, or a dashboard loading data from an API can all leave users confused when something unexpected happens.

Good error handling isn't just about preventing crashes. It's about making application behavior understandable when things don't go according to plan.

That's a useful goal for any developer.

Final thoughts

I think one sign of a mature application is that it handles failure as carefully as it handles success.

In Web3, this means distinguishing between a rejected request, a pending transaction, and a confirmed result. In other applications, the details will differ, but the principle remains the same.

Users don't expect every operation to work perfectly. They do expect the application to tell them what's happening.

What's one error message you've encountered that could have been much more helpful?

Top comments (1)

Collapse
 
cryptostrapon profile image
cryptostrapon •

Vague errors also train people to just sign again. Drainer sites copy exactly that with fake "failed, try again" popups.