Real NRE bug found via CS8602 triage in the Twilio 2FA verify-code path.
VerifyCodeCommandHandler dereferenced verificationCheck.Status.ToString()unguarded in two spots, while every other Status access in the same method used ?. — the author clearly knew Twilio can return a check with a null Status:
Response mapping (VerifyCodeResponse.Status, line 125): a null Status threw an NRE caught by the outer catch, so a valid verification result was reported to the caller as a generic INTERNAL_ERROR instead of the real status/outcome.
Audit write (twilio_verification_attempts.twilioStatus, line 180): the NRE there was swallowed by the logging try/catch, silently dropping the audit record for every null-status verification.
Fix:
Response mapping → verificationCheck.Status?.ToString() (VerifyCodeResponse.Status is string?).
Audit field → BsonValue.Create(verificationCheck.Status?.ToString()). Note: MongoDBs string→BsonValue implicit operator returns C# null (not BsonNull) for a null string, so a bare ?. would still throw ArgumentNullException in BsonDocument.Add — the regression test caught exactly this. BsonValue.Create maps null to BsonNull.Value.
Test: added a regression test via a protected virtual seam over the static Twilio SDK call, asserting a null-Status check (a) does not throw, (b) does not return INTERNAL_ERROR, and (c) still writes the audit record. All 17 handler tests pass. Build clean.
Scope: SpikerSoft.Workers.Notifications/Handlers/VerifyCodeCommandHandler.cs + its test. SonarQube rule external_roslyn:CS8602.
**Real NRE bug found via CS8602 triage** in the Twilio 2FA verify-code path.
`VerifyCodeCommandHandler` dereferenced `verificationCheck.Status.ToString()` **unguarded** in two spots, while every other `Status` access in the same method used `?.` — the author clearly knew Twilio can return a check with a null `Status`:
1. **Response mapping** (`VerifyCodeResponse.Status`, line 125): a null `Status` threw an NRE caught by the outer `catch`, so a valid verification result was reported to the caller as a generic `INTERNAL_ERROR` instead of the real status/outcome.
2. **Audit write** (`twilio_verification_attempts.twilioStatus`, line 180): the NRE there was swallowed by the logging `try/catch`, **silently dropping the audit record** for every null-status verification.
**Fix:**
- Response mapping → `verificationCheck.Status?.ToString()` (`VerifyCodeResponse.Status` is `string?`).
- Audit field → `BsonValue.Create(verificationCheck.Status?.ToString())`. Note: MongoDBs `string`→`BsonValue` implicit operator returns **C# null** (not `BsonNull`) for a null string, so a bare `?.` would still throw `ArgumentNullException` in `BsonDocument.Add` — the regression test caught exactly this. `BsonValue.Create` maps null to `BsonNull.Value`.
**Test:** added a regression test via a `protected virtual` seam over the static Twilio SDK call, asserting a null-Status check (a) does not throw, (b) does not return `INTERNAL_ERROR`, and (c) still writes the audit record. All 17 handler tests pass. Build clean.
Scope: `SpikerSoft.Workers.Notifications/Handlers/VerifyCodeCommandHandler.cs` + its test. SonarQube rule external_roslyn:CS8602.
Resolved in spikersoft-backend PR #366 (merged to master). Guarded null Twilio VerificationCheck.Status (CS8602): fixed an NRE that turned valid 2FA results into INTERNAL_ERROR and silently dropped audit records; added a regression test. All 17 handler tests pass. All build/test contexts green; merged past the non-blocking notify job. Closing.
Resolved in spikersoft-backend PR #366 (merged to `master`). Guarded null Twilio VerificationCheck.Status (CS8602): fixed an NRE that turned valid 2FA results into INTERNAL_ERROR and silently dropped audit records; added a regression test. All 17 handler tests pass. All build/test contexts green; merged past the non-blocking notify job. Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Real NRE bug found via CS8602 triage in the Twilio 2FA verify-code path.
VerifyCodeCommandHandlerdereferencedverificationCheck.Status.ToString()unguarded in two spots, while every otherStatusaccess in the same method used?.— the author clearly knew Twilio can return a check with a nullStatus:VerifyCodeResponse.Status, line 125): a nullStatusthrew an NRE caught by the outercatch, so a valid verification result was reported to the caller as a genericINTERNAL_ERRORinstead of the real status/outcome.twilio_verification_attempts.twilioStatus, line 180): the NRE there was swallowed by the loggingtry/catch, silently dropping the audit record for every null-status verification.Fix:
verificationCheck.Status?.ToString()(VerifyCodeResponse.Statusisstring?).BsonValue.Create(verificationCheck.Status?.ToString()). Note: MongoDBsstring→BsonValueimplicit operator returns C# null (notBsonNull) for a null string, so a bare?.would still throwArgumentNullExceptioninBsonDocument.Add— the regression test caught exactly this.BsonValue.Createmaps null toBsonNull.Value.Test: added a regression test via a
protected virtualseam over the static Twilio SDK call, asserting a null-Status check (a) does not throw, (b) does not returnINTERNAL_ERROR, and (c) still writes the audit record. All 17 handler tests pass. Build clean.Scope:
SpikerSoft.Workers.Notifications/Handlers/VerifyCodeCommandHandler.cs+ its test. SonarQube rule external_roslyn:CS8602.Resolved in spikersoft-backend PR #366 (merged to
master). Guarded null Twilio VerificationCheck.Status (CS8602): fixed an NRE that turned valid 2FA results into INTERNAL_ERROR and silently dropped audit records; added a regression test. All 17 handler tests pass. All build/test contexts green; merged past the non-blocking notify job. Closing.