paint-brush
Keep Your Happy Path Flowing, Not Nestingby@mcsee
New Story

Keep Your Happy Path Flowing, Not Nesting

by Maximiliano Contieri5mApril 13th, 2025
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Arrange your code so the main logic flows along the left margin, handling edge cases early with guard clauses.

Company Mentioned

Mention Thumbnail
featured image - Keep Your Happy Path Flowing, Not Nesting
Maximiliano Contieri HackerNoon profile picture

Keep your happy path flowing, not nesting

TL;DR: Arrange your code so the main logic flows along the left margin, handling edge cases early with guard clauses.

Problems 😔

Solutions 😃

  1. Use early returns
  2. Apply guard clauses
  3. Handle errors first
  4. Keep the main flow to the left
  5. Minimize nesting depth

Context 💬

When you write code with deeply nested conditional structures, you create "arrow code" or "pyramid of doom."


This makes your program's primary flow hard to follow as it zigzags deeper into indentation levels.


Your main logic (the "happy path") gets buried under layers of conditions, making the code harder to read, understand, and maintain.


This becomes even more problematic when dealing with internationalization and localization.


Nested conditionals often create fragmented contexts for strings, making accurate translations difficult because translators lose the surrounding context needed for proper translation.

Sample Code 📖

Wrong ❌

function processUserOrder(user, items) {
  if (user) {
    if (user.isActive()) {
      if (items.length > 0) {
        if (user.hasEnoughCredit()) {
          // The actual business logic is buried 4 levels deep
          let order = createOrder(user, items);
          notifyUser(user, 
            `Your order has been processed`);
          return order;
        } else {
          throw new Error("Insufficient credit");
        }
      } else {
        throw new Error("No items in cart");
      }
    } else {
      throw new Error("Your account is inactive");
    }
  } else {
    throw new Error("No user provided");
  }
}

Right 👉

function processUserOrder(user, items) {
  if (!user) throw new Error("No user provided");
  if (!user.isActive()) throw new Error("Your account is inactive");
  if (items.length === 0) throw new Error("No items in cart");
  if (!user.hasEnoughCredit()) throw new Error("Insufficient credit");

  const order = createOrder(user, items);
  notifyUser(user,
    `Your order has been processed`);
  return order;
}

// This is even more readable

function assertValidOrder(user, items) {
  if (!user) throw new Error("No user provided");
  if (!user.isActive()) throw new Error("Your account is inactive");
  if (items.length === 0) throw new Error("No items in cart");
  if (!user.hasEnoughCredit()) throw new Error("Insufficient credit");
}

function processUserOrder(user, items) {
  assertValidOrder(user, items);
  const order = createOrder(user, items);
  notifyUser(user,
    `Your order has been processed`);
  return order;
}

Detection 🔍

  • Semi-Automatic


You can detect this smell by looking for multiple indentation levels (more than 2 or 3).


You can also analyse ASTs with advanced linters.

Tags 🏷️

  • IFs

Level 🔋

  • Beginner

Why the Bijection Is Important 🗺️

When you write code with deep nesting, you break the clean Bijection between the logical flow of your business rules and their representation in code.


The real-world business process likely follows a series of validations followed by a main action, but deeply nested code obscures this natural sequence.


This one-to-one correspondence breaks down because the primary operation (what the function is supposed to do) gets buried deep in indentation layers.


The logical sequence of validations isn't separated from the main action.


By keeping your happy path to the left, you create a natural bijection between the actual process flow and the code structure, making it easier to reason about and modify in the future.

AI Generation 🤖

AI code generators often create nested conditional structures, especially when generating code from prompts that don't explicitly request early returns or guard clauses.


Many AI systems mimic common patterns they observe in training data, where deeply nested conditions are unfortunately prevalent.

AI Detection 🥃

Most AI code assistants can identify and fix this code smell with proper instructions.


If you ask an AI to refactor code to "use early returns" or "apply guard clauses" or "keep the happy path to the left," it can typically transform nested conditionals into flatter structures.


You can also prompt the AI to "reduce nesting in this function" or "refactor this code to avoid deep indentation," and set it as a meta-prompt following your style preferences.

Try Them! 🛠

Remember: AI Assistants make lots of mistakes


Suggested Prompt: Remove the deep nesting


Without Proper Instructions

With Specific Instructions

ChatGPT

ChatGPT

Claude

Claude

Perplexity

Perplexity

Copilot

Copilot

Gemini

Gemini

DeepSeek

DeepSeek

Meta AI

Meta AI

Qwen

Qwen

Conclusion 🏁

Keep your happy path to the left by using early returns and guard clauses, you will create more readable, maintainable code.


You communicate business logic more clearly, reduce cognitive load for other developers (including your future self), and create more resilient code to change.


Remember to handle the special cases early, and let your main logic flow naturally along the left margin. Your colleagues (and future you) will thank you.

Relations 👩‍❤️‍💋‍👨

Code Smell 102 - Arrow Code

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxvii

Disclaimer 📘

Code Smells are my opinion.

Credits 🙏

Photo by Alexander Hipp on Unsplash


A function should follow the "arrow shape" of reading naturally from top to bottom, not wander into deeper nesting like a poorly designed maze.


Venkat Subramaniam


Software Engineering Great Quotes


This article is part of the CodeSmell Series.