From 3fe1f592d618c28d090a8bfb6b44ef92e9baeec4 Mon Sep 17 00:00:00 2001 From: Ilyas Semmaoui Date: Tue, 18 May 2021 19:10:22 +0200 Subject: [PATCH] [lcl] handle temporary maintenance Sometimes different requests can temporarily return a HTTP 502 with a maintenance message --- modules/lcl/browser.py | 30 +++++++++++++++++++++--------- modules/lcl/pages.py | 33 ++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/modules/lcl/browser.py b/modules/lcl/browser.py index 2bcc75f660..52fc920030 100644 --- a/modules/lcl/browser.py +++ b/modules/lcl/browser.py @@ -53,7 +53,7 @@ Form2Page, DocumentsPage, ClientPage, SendTokenPage, CaliePage, ProfilePage, DepositPage, AVHistoryPage, AVInvestmentsPage, CardsPage, AVListPage, CalieContractsPage, RedirectPage, MarketOrdersPage, AVNotAuthorized, AVReroute, TwoFAPage, AuthentStatusPage, FinalizeTwoFAPage, - PasswordExpiredPage, ContractRedirectionPage, + PasswordExpiredPage, ContractRedirectionPage, MaintenancePage, ) @@ -268,11 +268,8 @@ def init_login(self): if self.password_expired_page.is_here(): raise BrowserPasswordExpired(self.page.get_message()) - if ( - not self.contracts and not self.parsed_contracts - and (self.contracts_choice.is_here() or self.contracts_page.is_here() - or self.contract_redirection_page.is_here()) - ): + if (not self.contracts and not self.parsed_contracts + and (self.contracts_choice.is_here() or self.contracts_page.is_here())): # On the preRoutageLogin page we gather the list of available contracts for this account self.contracts = self.page.get_contracts_list() # If there is not multiple contracts then self.contracts will be empty @@ -345,6 +342,21 @@ def handle_sms(self): self.location('/outil/UWAF/Otp/validationCodeOtp?codeOtp=%s' % self.code) self.page.check_otp_error(otp_sent=True) + def go_to_accounts(self): + try: + self.accounts.go() + except ServerError as e: + # Sometimes this page can return a 502 with a message "Pour raison de maintenance informatique, + # votre espace « gestion de comptes » est momentanément indisponible. Nous vous invitons à vous + # reconnecter ultérieurement. Nous vous prions de bien vouloir nous excuser pour la gêne occasionnée." + if e.response.status_code == 502: + maintenance_page = MaintenancePage(self, e.response) + error_message = maintenance_page.get_message() + if maintenance_page.get_error_code() == 'BPI-50': + raise BrowserUnavailable(error_message) + raise AssertionError('An unexpected error occurred: %s' % error_message) + raise + @need_login def connexion_bourse(self): self.location('/outil/UWBO/AccesBourse/temporisationCar?codeTicker=TICKERBOURSECLI') @@ -362,7 +374,7 @@ def deconnexion_bourse(self): self.disc.stay_or_go() if self.contract_redirection_page.is_here() and self.page.should_submit_redirect_form(): self.page.submit_redirect_form() - self.accounts.go() + self.go_to_accounts() if self.login.is_here(): # When we logout we can be disconnected from the main site self.do_login() @@ -493,7 +505,7 @@ def get_accounts(self): self.go_back_from_life_insurance_website() # retrieve accounts on main page - self.accounts.go() + self.go_to_accounts() for a in self.page.get_accounts_list(name=owner_name): if not self.check_accounts(a): continue @@ -567,7 +579,7 @@ def get_accounts_list(self): else: self.get_accounts() - self.accounts.go() + self.go_to_accounts() deferred_cards = self.page.get_deferred_cards() diff --git a/modules/lcl/pages.py b/modules/lcl/pages.py index d999483dc1..dc9584362c 100644 --- a/modules/lcl/pages.py +++ b/modules/lcl/pages.py @@ -200,6 +200,18 @@ def is_here(self): return self.response.status_code == 302 +class MaintenancePage(HTMLPage): + def get_error_code(self): + return Regexp( + CleanText('//div[contains(text(), "CODE ERREUR : ")]'), + r'CODE ERREUR : (.*)', + default=None, + )(self.doc) + + def get_message(self): + return CleanText('//div[@id="indispo_texte"]')(self.doc) + + class ContractsPage(LoginPage, PartialHTMLPage): def on_load(self): # after login we are redirect in ContractsPage even if there is an error at login @@ -628,11 +640,22 @@ def open_transaction_page(self, tr): Attr('.', 'href')(tr._el), method='POST', ) - - return self.browser.open( - '/outil/UWLM/ListeMouvementsParticulier/accesDetailsMouvement?element=%s' % row, - method='POST', - ) + try: + return self.browser.open( + '/outil/UWLM/ListeMouvementsParticulier/accesDetailsMouvement?element=%s' % row, + method='POST', + ) + except ServerError as e: + # Sometimes this page can return a 502 with a message "Pour raison de maintenance informatique, + # votre espace « gestion de comptes » est momentanément indisponible. Nous vous invitons à vous + # reconnecter ultérieurement. Nous vous prions de bien vouloir nous excuser pour la gêne occasionnée." + if e.response.status_code == 502: + maintenance_page = MaintenancePage(self.browser, e.response) + error_message = maintenance_page.get_message() + if maintenance_page.get_error_code() == 'BPI-50': + raise BrowserUnavailable(error_message) + raise AssertionError('An unexpected error occurred: %s' % error_message) + raise def fix_transaction_stuff(self, obj, tr_page): if obj.category == 'RELEVE CB': -- GitLab