Skip to content

Commit aea2d96

Browse files
committed
fix(flows): scope blank retry fallback to date and datetime formats
1 parent 6d76858 commit aea2d96

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

apps/worker/__tests__/get-user-data.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,14 +531,14 @@ describe("getUserData — attempt counter (Bug B fix)", () => {
531531
})
532532
})
533533

534-
test("falls back to the step message when retryMessage is blank (empty text is silently dropped downstream)", async () => {
534+
test("keeps the long-standing blank retry behavior for non-webview formats (sends the blank retry text unchanged)", async () => {
535535
await getUserData(makeProps(ReplyFormat.email, { retryMessage: "" }, 1))
536536

537537
expect(chatQueueAdd).toHaveBeenCalledWith("sendFlowMessage", {
538538
type: "sendFlowMessage",
539539
data: expect.objectContaining({
540540
step: expect.objectContaining({
541-
text: "Please enter your email",
541+
text: "",
542542
}),
543543
}),
544544
})

apps/worker/src/integration/handlers/get-user-data.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -328,21 +328,33 @@ async function handleSkipOrError(
328328
"getUserData: input rejected, retrying",
329329
)
330330

331-
// `retryMessage` defaults to "" (schema has no minimum), and an empty
332-
// prompt is silently dropped by sendChatMessage — the contact would see
333-
// nothing at all on an invalid reply. Fall back to the step's main
334-
// message whenever retryMessage is blank, so the retry always re-prompts
335-
// (and, for date/datetime on capable channels, re-offers the picker
336-
// button).
337331
await sendMessage(
338332
props,
339-
step.retryMessage.trim() || step.message,
333+
resolveRetryPromptText(step),
340334
((ctx?.variables.conversation.challengeAttempts?.value as number) ?? 1) + 1,
341335
)
342336

343337
return { result: undefined, status: "retry" }
344338
}
345339

340+
/**
341+
* `retryMessage` defaults to "" (schema has no minimum) and an empty prompt
342+
* is silently dropped by the send path. For the webview formats
343+
* (date/datetime) a blank retry falls back to the step's main message so the
344+
* retry always re-offers the picker button — a silent retry would strand the
345+
* contact with no way back to the picker. Every other reply format keeps the
346+
* long-standing behavior (blank retry sends nothing): flows built before
347+
* this feature may rely on that silence, and typed input still works there.
348+
*/
349+
function resolveRetryPromptText(step: GetUserDataStepSchema): string {
350+
const isWebviewFormat = Boolean(
351+
DATE_TIME_WEBVIEW_MODE_BY_REPLY_FORMAT[step.replyFormat],
352+
)
353+
return isWebviewFormat
354+
? step.retryMessage.trim() || step.message
355+
: step.retryMessage
356+
}
357+
346358
async function validateUserData(
347359
props: ExecuteStepProps<GetUserDataStepSchema>,
348360
): Promise<ReplyValidationResult> {

0 commit comments

Comments
 (0)