DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Code Smell 157 - Balance at 0
Maxi Contieri
Maxi Contieri

Posted on • Originally published at maximilianocontieri.com

Code Smell 157 - Balance at 0

Today I expected a payment in my wallet. The balance was 0. I panicked.

TL;DR: Null is not 0. Error is not 0. just 0 is 0.

Problems

Solutions

  1. Make a clear distinction between a Zero and an error.

Context

I read a lot about security issues.

Especially on crypto.

Last week, I read about a crypto hack thread.

When my wallet showed me 0 as a balance, I panicked.

It was just a UX smell.

The blockchain was unreachable πŸ’©

Sample Code

Wrong

"""
Below code is automatically generated by code-davinci-002 on GTP3 Codex

1. check balance with blokchain
2. If blockchain is unreachable show 0 as the balance
"""

import requests
import json

def get_balance(address):
    url = "https://blockchain.info/q/addressbalance/" + address
    response = requests.get(url)
    if response.status_code == 200:
        return response.text
    else:
        return 0      



Enter fullscreen mode Exit fullscreen mode

Right

"""
Below code is automatically generated by code-davinci-002 on GTP3 Codex

1. check balance with blockchain
2. If blockchain is unreachable throw an error
"""

import requests
import json

def get_balance(address):
    url = "https://blockchain.info/q/addressbalance/" + address
    response = requests.get(url)
    if response.status_code == 200:
        return response.text
    else:
        raise BlockchainNotReachableError("Error reaching blockchain")
Enter fullscreen mode Exit fullscreen mode

Detection

[X] Manual

This is a design smell.

We can find patterns when an exception or return code is thrown and masked with a 0.

Tags

  • UX

Conclusion

Always follow The Least Astonishment principle as a guide.

Relations

More Info

Credit

Photo by Jasmin Sessler on Unsplash

Disclaimer

Code Smells are just my opinion.

My real criticism with Null is that it brings back again unnecessarily all the agony of having to choose whether to run your program fast without checking or run it slow with checking.

Tony Hoare (Null Inventor)


This article is part of the CodeSmell Series.

Top comments (5)

Collapse
jmfayard profile image
Jean-Michel Fayard πŸ‡«πŸ‡·πŸ‡©πŸ‡ͺπŸ‡¬πŸ‡§πŸ‡ͺπŸ‡ΈπŸ‡¨πŸ‡΄ • Edited on

I have not read your complete series, but raising an exception is also an error for me :)
Throwing exceptions should only be done in exceptional cases where the reasonable thing to do is to crash.
The network not working on the other hand is just life and something to be dealt with.
So I would use a plein result type like all Either

Collapse
mcsee profile image
Maxi Contieri Author

Exceptions are for exceptional cases

The contrary is another smell

but 'network not working' is an exceptional case that, IMHO, should be handled by the UI.

and return codes are not an option

Collapse
jmfayard profile image
Jean-Michel Fayard πŸ‡«πŸ‡·πŸ‡©πŸ‡ͺπŸ‡¬πŸ‡§πŸ‡ͺπŸ‡ΈπŸ‡¨πŸ‡΄ • Edited on

I was sure you handled that in your Impressive serie!

I completely agree with Use Exceptions just for unexpected situations and not for flow control because they are handy goto.

I go further than you though. By unexpected situations, I mean a programmer error (like your for each loop), or your VM going out of memory.

The network to fail on the other hand is a case that a programmer must totally expect. So I would use a Either<Failure, Success> to force him to always handle this case.

Obviously that works only in programming who supports lambdas and generics. If not fallback on the handy gotos.

Thread Thread
mcsee profile image
Maxi Contieri Author

can you elaborate on Either
is this some kind of flag boolean function ?

Thread Thread
jmfayard profile image
Jean-Michel Fayard πŸ‡«πŸ‡·πŸ‡©πŸ‡ͺπŸ‡¬πŸ‡§πŸ‡ͺπŸ‡ΈπŸ‡¨πŸ‡΄

Going tomorrow on a trip, and short of time, but I've found a DEV article that sums it well

🌚 Life is too short to browse without dark mode