Refactoring 031 – Removing OOPs

Replace vague error messages with specific, actionable feedback that helps users solve problems.


This content originally appeared on HackerNoon and was authored by Maximiliano Contieri

Give users help, not confusion

TL;DR: Replace vague error messages with specific, actionable feedback that helps users solve problems.

Problems Addressed 😔

  • User confusion and frustration
  • No actionable guidance provided
  • Technical jargon
  • Poor Unhandled errors
  • Poor UX
  • Poor error recovery
  • Incomplete Error Information
  • Decreased user trust
  • Generic messaging
  • Silent Failures

Related Code Smells 💨

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xx-we-have-reached-100

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

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

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

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

Steps 👣

  1. Identify all generic error messages in your codebase that use terms like "Oops", "Something went wrong", or "An error occurred"
  2. Replace generic messages with specific descriptions of what happened
  3. Add actionable guidance telling users exactly what they can do to resolve the issue
  4. Implement proper internal logging to capture technical details for developers
  5. Add monitoring alerts to notify the development team when errors occur frequently

Sample Code 💻

Before 🚨

function processPayment(paymentData) {
  try {
    // Too broad try catch  
    validatePayment(paymentData);
    chargeCard(paymentData);
    sendConfirmation(paymentData.email);
  } catch (error) {
    // Generic error message shown to user
    return {
      success: false,
      userMessage: "Oops! Something went wrong. Please try again.",
      error: error.message
    };
  }
}

function handleError(res, error) {
  // Exposing HTTP 500 to users
  res.status(500).json({
    message: "Internal Server Error",
    error: error.message
  });
}

After 👉

function processPayment(paymentData) {
  try {
    validatePayment(paymentData);
    // This catch is specific to payment validation
  } catch (error) {
    // 1. Identify all generic error messages in your codebase
    // that use terms like "Oops", "Something went wrong", 
    // or "An error occurred"    
    // 2. Replace generic messages 
    // with specific descriptions of what happened
    // 3. Add actionable guidance telling users 
    // exactly what they can do to resolve the issue
    // 4. Implement proper internal logging 
    // to capture technical details for developers
    logger.error('Payment validation failed', {
      userId: paymentData.userId,
      error: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString()
    });
    // 5. Add monitoring alerts to notify 
    // the development team when errors occur frequently    
    alerting.notifyError('PAYMENT_VALIDATION_FAILED', error);
    if (error.code === 'INVALID_CARD') {
      return {
        success: false,
        userMessage: "Your card information" + 
        " appears to be incorrect." +
        "Please check your card number," + 
        " expiry date, and security code."
      };
    }
    return {
      success: false,
      userMessage: "There was a problem validating" +
      " your payment." +
      "Please try again or contact support."
    };
  }

  // You should break this long method
  // Using extract method
  try {
    chargeCard(paymentData);
  } catch (error) {
    logger.error('Card charging failed', {
      userId: paymentData.userId,
      error: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString()
    });
    alerting.notifyError('CARD_CHARGING_FAILED', error);
    if (error.code === 'INSUFFICIENT_FUNDS') {
      return {
        success: false,
        userMessage: "Your payment couldn't be processed"+
        " due to insufficient funds. " +
        "Please use a different payment method" + 
        " or contact your bank."
      };
    }
    if (error.code === 'CARD_EXPIRED') {
      return {
        success: false,
        userMessage: "Your card has expired. " +
        "Please update your payment method with a current card."
      };
    }
    return {
      success: false,
      userMessage: "There was a problem processing your payment." +
      " Please try again or contact support."
    };
  }

  try {
    sendConfirmation(paymentData.email);
  } catch (error) {
    logger.error('Confirmation sending failed', {
      userId: paymentData.userId,
      error: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString()
    });
    alerting.notifyError('CONFIRMATION_FAILED', error);
    return {
      success: true,
      userMessage: "Payment processed successfully,"+
      " but we couldn't send the confirmation email." +
      " Please check your email address or contact support."
    };
  }

  return { success: true,
          userMessage: "Payment processed successfully." };
}

Type 📝

  • [x] Manual

Safety 🛡️

This refactoring changes the behavior and is safe if you keep logging and alerts active for debugging.

Avoid removing details needed by support teams.

The risk of breaking changes is low since you're improving existing error handling rather than changing core business logic.

Why is the Code Better? ✨

You give users useful guidance instead of confusion.

You create a better user experience by providing clear, actionable feedback instead of confusing technical jargon.

Users understand what went wrong and know their next steps.

You separate concerns by keeping technical details in logs while showing business-friendly messages to users.

Your support team gets better debugging information through structured logging.

You can proactively address system issues through monitoring alerts before users report them.

You keep technical information away from them, but still record it for faster issue resolution.

How Does it Improve the Bijection? 🗺️

You keep a closer match between the real world and your model. Instead of vague "Oops" messages, your system speaks in clear terms that reflect actual events.

Error messages in the real world contain specific information about what went wrong and how to fix it.

A cashier doesn't say "Oops, something went wrong" when your card is declined - they tell you the specific issue and suggest solutions.

This refactoring aligns the software model with Bijection error communication patterns, making the system more intuitive and helpful for users

Limitations ⚠️

You must be careful not to expose sensitive system information that could help attackers.

Some errors may need to remain generic for security reasons (like authentication failures).

Additionally, creating specific error messages requires more development time and thorough testing of error scenarios.

Refactor with AI 🤖

Suggested Prompt: 1. Identify all generic error messages in your codebase that use terms like "Oops", "Something went wrong", or "An error occurred" 2. Replace generic messages with specific descriptions of what happened 3. Add actionable guidance telling users exactly what they can do to resolve the issue 4. Implement proper internal logging to capture technical details for developers 5. Add monitoring alerts to notify the development team when errors occur frequently

| Without Proper Instructions | With Specific Instructions | |----|----| | ChatGPT | ChatGPT | | Claude | Claude | | Perplexity | Perplexity | | Copilot | Copilot | | You | You | | Gemini | Gemini | | DeepSeek | DeepSeek | | Meta AI | Meta AI | | Grok | Grok | | Qwen | Qwen |

Tags 🏷️

  • Exceptions

Level 🔋

  • [x] Intermediate

Related Refactorings 🔄

https://hackernoon.com/refactoring-014-how-to-remove-if?embedable=true

See also 📚

https://hackernoon.com/fail-fast-philosophy-explained-si963vk9?embedable=true

https://www.morling.dev/blog/whats-in-a-good-error-message/?embedable=true

https://ulrikapark.wordpress.com/2021/05/03/are-you-sure-people-get-happy-about-your-oops-error-messages-or-does-it-lower-their-trust-in-your-software/?embedable=true

https://www.sonarsource.com/learn/error-handling-guide/?embedable=true

Credits 🙏

Image by Ryan McGuire on Pixabay


This article is part of the Refactoring Series.

https://maximilianocontieri.com/how-to-improve-your-code-with-easy-refactorings?embedable=true

\


This content originally appeared on HackerNoon and was authored by Maximiliano Contieri


Print Share Comment Cite Upload Translate Updates
APA

Maximiliano Contieri | Sciencx (2025-08-11T02:00:05+00:00) Refactoring 031 – Removing OOPs. Retrieved from https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/

MLA
" » Refactoring 031 – Removing OOPs." Maximiliano Contieri | Sciencx - Monday August 11, 2025, https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/
HARVARD
Maximiliano Contieri | Sciencx Monday August 11, 2025 » Refactoring 031 – Removing OOPs., viewed ,<https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/>
VANCOUVER
Maximiliano Contieri | Sciencx - » Refactoring 031 – Removing OOPs. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/
CHICAGO
" » Refactoring 031 – Removing OOPs." Maximiliano Contieri | Sciencx - Accessed . https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/
IEEE
" » Refactoring 031 – Removing OOPs." Maximiliano Contieri | Sciencx [Online]. Available: https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/. [Accessed: ]
rf:citation
» Refactoring 031 – Removing OOPs | Maximiliano Contieri | Sciencx | https://www.scien.cx/2025/08/11/refactoring-031-removing-oops/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.