DEV Community

loading...
Cover image for Code Smell 72 - Return Codes

Code Smell 72 - Return Codes

Maxi Contieri
Learn something new every day. - I am a senior software engineer working in industry, teaching and writing on software design, SOLID principles, DDD and TDD.
・2 min read

APIs, Return codes, C Programming Language, We've all been there.

TL;DR: Don't return codes to yourself. Raise Exceptions.

Problems

  • IFs

  • Code Polluting

  • Outdated documentation

  • Coupling to accidental codes.

  • Functional logic polluted.

Solutions

  1. Change Ids and return Generic Exceptions.

  2. Distinguish Happy Path from Exception Path.

Sample Code

Wrong

function createSomething(arguments) {
    //Magic Creation
    success = false; //we failed

    //We failed to create
    if (!success) {
        return {
            object: null,
            errorCode: 403,
            errorDescription: 'We didnt have permission to create...'
        };
    }

    return {
        object: createdObject,
        errorCode: 400,
        errorDescription: ''
    };
}

var myObject = createSomething('argument');
if (myObject.errorCode != 400) {
    console.log(myObject.errorCode + ' ' + myObject.errorDescription)
}
//but myObject does not hold My Object but an implementative
//and accidental array 
//from now on me need to remember this
Enter fullscreen mode Exit fullscreen mode

Right

function createSomething(arguments) {
    //Magic Creation
    success = false; //we failed

    //We failed to create
    if (!success) {
        throw new Error('We didnt have permission to create...');
    }

    return createdObject;
}

try {
    var myObject = createSomething('argument');
    //no IFS, just happy path
} catch (exception) {
    //deal with it!
    console.log(exception.message);
}
// myObject holds my expected object
Enter fullscreen mode Exit fullscreen mode

Detection

We can teach our linters to find patterns of integer and strings returns coupled with ifs and return checking.

Tags

  • Exceptions

Conclusion

Ids and codes are external identifiers.

They are useful when you need to interact with an external system (for example an API Rest).

We should not use them on our own systems and our own internal APIs.

Create and raise generic exceptions.

Only create specific exceptions if you are ready to handle them, and they have specialized behavior.

Don't create anemic Exceptions.

Avoid immature and premature optimized languages favoring return codes.

Relations

More info

Clean code

Credits

Photo by Alex Hay on Unsplash


Error handling is important, but if it obscures logic, it’s wrong.

Robert Martin


This article is part of the CodeSmell Series.

Discussion (4)

Collapse
yoursunny profile image
Junxiao Shi

Tell the designers of Go programming language.
There's no exception.
Error checking everywhere.

Collapse
dakujem profile image
Andrej Rypo

That's exactly the same thing that occured to me, at first. Except, in Go they call "them" Errors and they are the mechanism that serves the same purpose, implemented different way. In the same manner you probably shouldn't return error codes in Go, but return Error objects as the second return value.

Collapse
mcsee profile image
Maxi Contieri Author

Yes. That is why I would chose a more mature language and not one based on the 60s.

But if performance is the ONLY concern I think we can tolerate lots of code smells . It is a price to pay

Collapse
mcsee profile image
Maxi Contieri Author

if you read this sentence on the article above you will find your own answer

Avoid immature and premature optimized languages favoring return codes