Ashhar Ahmad Khan created FINERACT-2786:
-------------------------------------------

             Summary: EmailMessage.pendingEmail() throws NullPointerException 
on /v1/email CREATE due to hardcoded null emailCampaign
                 Key: FINERACT-2786
                 URL: https://issues.apache.org/jira/browse/FINERACT-2786
             Project: Apache Fineract
          Issue Type: Bug
            Reporter: Ashhar Ahmad Khan


What is broken

EmailMessageAssembler.assembleFromJson(), the method that builds an 
EmailMessage from a /v1/email CREATE request, calls 
EmailMessage.pendingEmail(group, client, staff, null, emailSubject, message, 
emailAddress, null), passing emailCampaign as a hardcoded null. 
pendingEmail()'s body unconditionally calls 
.setStatusType(emailCampaign.getStatus()) with no null check, so it throws 
NullPointerException on every single /v1/email CREATE request, regardless of 
which valid fields are supplied. This makes /v1/email CREATE completely 
unusable today, independent of and in addition to the validator bug fixed in 
FINERACT-2785.

Why it's broken

Runtime confirmed with a Mockito test calling assembleFromJson() with a valid 
clientId and emailMessage payload. The call throws NullPointerException from 
inside pendingEmail(), not from anywhere in EmailMessageAssembler itself.

Grepped every caller of pendingEmail() across the codebase. Found three other 
call sites, two in EmailCampaignWritePlatformCommandHandlerImpl and one in 
UpdateEmailOutboundWithCampaignMessageTasklet, and all three always pass a 
real, non-null EmailCampaign. The /v1/email assembler is the only caller that 
passes null. The email_campaign_id column itself is nullable at the JPA/DB 
level, confirming the schema always intended campaign-less emails to be valid. 
pendingEmail() was just never written to handle that case because nothing 
called it that way until /v1/email's assembler was added.

EmailMessage.java already contains a second factory method, instance(), sitting 
right next to pendingEmail(), which takes statusType as an explicit parameter 
instead of deriving it from emailCampaign.getStatus(), so it is null safe by 
construction. Grep confirms zero production callers currently used instance() 
before this fix, it was dead code with the right shape, not an established 
pattern.

Changes made
 * EmailMessageAssembler.assembleFromJson() now calls 
EmailMessage.instance(group, client, staff, null, 
EmailMessageStatusType.PENDING, emailSubject, message, null, emailAddress, 
null) instead of pendingEmail(...). This required zero changes to 
EmailMessage.java itself, so it carries zero risk to the three working campaign 
driven callers of pendingEmail().
 * Added EmailMessageAssemblerTest.java, a regression test confirming 
assembleFromJson() no longer throws and produces a PENDING EmailMessage when 
only clientId is supplied.

Related

FINERACT-2785 (validator fix, separate bug, same resource, found during the 
same investigation)



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to