mohd-faraz

_blogs

// blogs / 20260812.md

Dev Log: August 12 Wrap-up

2026-08-12
#backend#error-handling#crm-integration#testing

Overview

Today was about closing the loop on the lead intake work I started yesterday. I spent most of my time bridge-building between the backend's strict error handling and the frontend's need for actual, human-readable feedback. It was a lot of plumbing, but the system feels much more resilient now.

What I Worked On

Bridging the Error Gap

Yesterday I was wrestling with how our ApplicationException just threw generic codes at the UI. It’s frustrating for a user to see 'Error 500' when the real issue is just a duplicate submission. Today, I built a small translation layer. Instead of the frontend guessing why a lead submission failed, the backend now sends a structured response that distinguishes between a 'duplicate entry,' a 'validation error,' and an actual server meltdown.

It’s one of those things that seems simple until you realize you have to touch a dozen different service callers to make it consistent. I ended up creating a standard response wrapper so we don't have to reinvent the wheel next time we add a new form.

// Simple wrapper to make error responses more descriptive
public class FeedbackResponse {
    private String status;
    private String message;
    private Map<String, String> details;

    public FeedbackResponse(String status, String message) {
        this.status = status;
        this.message = message;
        this.details = new HashMap<>();
    }
    
    public void addDetail(String key, String value) {
        this.details.put(key, value);
    }
}

Testing the 'Sticky' Lead Logic

I also spent a good chunk of the afternoon stress-testing the deduplication logic I wrote yesterday. I wanted to be absolutely sure that adding the form type to the unique constraint wouldn't cause issues for users who genuinely need to submit multiple requests—like someone submitting a support ticket and then a sales inquiry back-to-back.

I ran through a few scenarios in the staging environment, and the merge logic held up perfectly. It’s satisfying to see the CRM records updating with new info rather than creating three different entries just because a user hit 'submit' twice.

Wrapping Up

The intake flow feels a lot more robust now. The communication between the layers is finally clear, and we aren't losing data to aggressive overwrites anymore. Tomorrow, I’m planning to circle back to some of the AI guardrail feedback—the score-based system I set up last week is doing its job, but there are a few edge cases in the 'help' intent that still need a little nudge.