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)