In web2 , our rest api call are confined with just request and response framework . In web3 , for this particular solana , our transaction goes through this full commitment lifecycle:
send() → Processed ✓ → Confirmed ✓ → Finalized ✓
| State | What it means |
|---|---|
| Processed | Validator received the transaction |
| Confirmed | 2/3 of stake weight agrees |
| Finalized | Permanent — cannot be rolled back |
sendAndConfirmTransaction() polls internally through all 3 states and resolves once finalized.
Pay to attempt, not just to succeed
Unlike of web2 , on which failed transaction incur nothing ,in web3 , we pay to attempt, not just to succeed. The chain ran the instruction, hit the error, and charged the fee anyway.
During my day 19 of 100 days of solona , I revealed:
Status: Error processing Instruction 0 — custom program error: 0x1
0x1=InsufficientFundson the System Program
What the failed tx showed
| Field | Value from my terminal |
|---|---|
| Error code | custom program error: 0x1 |
| Fee charged |
0.000005 SOL (still deducted) |
| Compute Units |
150 consumed |
| Balance change |
1.468975 → 1.46897 (fee only) |
| Log message | Transfer: insufficient lamports 1468970000, need 500000000000 |
Final Note : err.logs vs console.error
err.logs |
console.error(err) |
|
|---|---|---|
| Source | Solana runtime (on-chain) | Node.js |
| Tells you | WHY the chain rejected it | WHERE your code broke |
| Can be undefined? | Yes — if tx never reached the chain | No — always present |
| Example | Transfer: insufficient lamports… |
SendTransactionError: simulation failed… |
Recommendation : Always use both:
} catch (err) {
console.error("JS error:", err.message); // WHERE it broke
if (err.logs) {
console.log("Chain logs:", err.logs); // WHY chain rejected
}
}
This much upto my learning journey for now . Will be updating other blog soon too .

Top comments (0)