Button of choosing reply always expires
MrOrz opened this issue · 2 comments
MrOrz commented
MrOrz commented
Seems that context is empty after providing text that has 100% match.
It is supposed to have at least a data
attribute and a new sessionId
. No data
in context will trigger this logic, responding that the button is expired.
Note that the action buttons do have sessionId
in its postback data, so data
is passed to choosingArticle
handler correctly. Then what happens when choosingArticle
returns its data
?
Still needs further investigation.
MrOrz commented
Root cause
handlePostback
, a function that returns {context: data}
, is used in handlers that should return {data}
.
handleInput
,handlePostback
andprocessImage
are top-level functions that returns{context, replies}
forsingleUserHandler
to set redis context and submit replies.- These functions calls handlers such as
initState
andchoosingArticle
, who returns data in{data, replies, ...}
format. - However, in
initState
andchoosingArticle
, in some scenarios we may return results fromhandlePostback
.- The caller of
initState
expects a result in the form{data, replies, ...}
but in this case it returns{context, replies}
- The caller tries to grab
data
(which isundefined
in this case) and put incontext
, thus the context is dropped.
- The caller of
- After context is dropped, any postback action will trigger this logic, rendering the "button is expired" error.
- In the unit test, we mock the return result of
handlePostback
all together, so that we cannot spot this issue.
Suggested fix
- In the context of handlers such as
initState
andchoosingArticle
, instead of callinghandlePostback({data}, NEXT_ACTION)
, we should call the handler for theNEXT_ACTION
and return its result. This ensures that the signature stays the same. - We do not mock the called handler in unit test so that we can inspect the response of the called handler. Although the snapshot may overlap and changes to the called handler may incur multiple snapshot changes, we can at least see if the full response is as expected.
Impact
handlePostback({ data }, 'CHOOSING_ARTICLE', event, userId)
IninitState
under conditionedgesSortedWithSimilarity.length === 1 && hasIdenticalDocs
- --> If there is only 1 identical text, the resulting buttons have no context and always yields "button is expired" error
- Example: the example in the ticket description
handlePostback({ data }, 'CHOOSING_REPLY', event, userId)
inchoosingArticle
under conditionarticleReplies.length === 1