[FIX] pos_hobex: no crash on hobex timeout, poll transaction state instead of starting a new payment (18.0) - #2
Open
geraldaistleitner wants to merge 1 commit into
Conversation
…tate instead of restarting Forward-port of the 17.0 fix, adapted to the RPC proxies of this branch. - hobex_start_sync_transaction: `response` was referenced in the except handler before assignment when requests.post itself raised (e.g. read timeout after 80s) -> UnboundLocalError. The transaction now stays pending (the outcome is unknown, the customer may still finish at the terminal) and responseCode -1 is returned. - proxy_hobex_status_request: error results carry a code (not_found / no_answer), exceptions from update_hobex_state are reported as no_answer. - hobex_reversal_transaction: return (None, None) on exceptions. - _update_transaction_with_hobex_result: receipt download (cvm=1) can no longer turn a successful payment into an error; state mapping evaluates 'state' first and no longer raises NameError for unknown values. - POS: a -1 answer no longer counts as a hobex result - the client asks for the state of the existing transaction instead of starting a new one (double charge). INPROGRESS no longer stores responseCode 0 (the line counted as paid on the next Send); the poll branch resolves the outer promise; not_found resets the transaction id; all handlers cope with false/null results from silentCall.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Forward-port of #1 (17.0) to 18.0, adapted to the RPC-proxy architecture of this branch.
Problem
hobex_start_sync_transactionstill crashes in its ownexcepthandler on 18.0 when hobex does not answer the payment request within the 80 s read timeout:responseis only assigned inside thetry, so wheneverrequests.postitself raises the handler hits an unbound name. On 18.0 the exception propagates out ofproxy_hobex_payment_request,pos.data.silentCallswallows it and resolves withfalse, and_hobex_handle_payment_request_donethen readsfalse.responseCodeand shows "undefined: undefined". Odoo core puts the line intoretry, so the cashier can only delete the card line (and rebook as cash) or press Send again, which starts a second hobex transaction while the first one is frequently still completing at the terminal. We have had to repair several 17.0 production orders where the card charge went through but the order was finalized with a cash payment.While porting I found three more client-side problems on this branch that make the recovery path unusable:
_hobex_handle_status_update_responsestoreshobex_responseCode = "0"before checking the state. After anINPROGRESSanswer the next Send therefore takes the "transaction was already successful" branch and marks an unfinished payment as paid.send_payment_requestcalls_hobex_update_payment_status(order, uuid)without chaining its promise, so the outer promise never resolves and the line hangs. The branch was unreachable anyway because"hobex_responseCode" in lineis always true (models.jsinitialises the field tofalse)._hobex_handle_status_connection_failurereturnsPromise.rejectand never resolves; anullreversal result (hobex timeout) crashes_hobex_handle_reversal_response.Changes
Server
hobex_start_sync_transaction:transactionlookup moved out of thetry. On any exception the transaction now stayspendingwith the error inmessageand the method returnsresponseCode -1. It no longer guessesfailed: after a timeout the outcome of a card payment is unknown and the customer may still complete it at the terminal. Timeouts and connection errors get a readable message.proxy_hobex_status_request: error results carry acode(not_found/no_answer) so the POS can tell "hobex never got this transaction, start a new one" from "hobex unreachable, ask again". An exception fromupdate_hobex_stateis caught and reported asno_answerinstead of leaking throughsilentCallasfalse.hobex_reversal_transaction: return(None, None)on exceptions (as on 19.0) instead ofNone, which madeproxy_hobex_reversal_requestraise on unpacking._update_transaction_with_hobex_resultcvm == 1) is wrapped in its own try/except, so a receipt hiccup can no longer turn a successful payment into a-1errorstatefirst and falls back toresponseText, with a safe default ofokplus a warning for unknown values. The 18.0 code leftstateunassigned (NameError) for any value other than OK/VOID/INPROGRESS. I evaluatestatefirst because the POS client keys on that field; please double check against a real v2 status response.update_hobex_state:res.get('state').POS client (
payment_hobex.js)-1answer is no longer stored as the line's hobex result. The client immediately asksproxy_hobex_status_requestfor the real state (the server waits for the terminal itself) and resolves from that: success →donewith all card details, abort/failure →retry, transaction id reset so a new attempt is possible.INPROGRESSno longer stores a response code; the cashier gets a German message to finish at the terminal and press Send again.not_foundresets the transaction id;no_answerkeeps it.false/nullresults fromsilentCalland always resolve, so a line can no longer hang.retry), so a hobex outage never blocks finishing an order.Version bumped to 18.0.2.1.1.
Testing
Syntax checked (
py_compile,node --check); not runtime-tested on 18.0, we are preparing our upgrade from 17.0. The scenario is easy to reproduce with a real terminal by not presenting a card for ~90 s: the line should enddoneonce the customer taps, and8004should be reported when the transaction is aborted at the terminal.