Skip to content

added keyword retry listener#14

Open
MarvKler wants to merge 8 commits intoMarketSquare:mainfrom
MarvKler:main
Open

added keyword retry listener#14
MarvKler wants to merge 8 commits intoMarketSquare:mainfrom
MarvKler:main

Conversation

@MarvKler
Copy link

@MarvKler MarvKler commented Dec 2, 2025

No description provided.

MarvKler and others added 2 commits November 5, 2025 18:25
* set loglevel correctly

* gitignore

---------

Co-authored-by: Marvin Klerx <marvin.klerx@imbus.de>
* v1 keywordretrylistener

* v1 keywordretrylistener

* retry kewords if failed

* set loglevel for keyword retry

* docs

* docs

* tests

* removed status param

* removed not required imports

---------

Co-authored-by: Marvin Klerx <marvin.klerx@imbus.de>
@MarvKler
Copy link
Author

MarvKler commented Dec 2, 2025

@Snooz82 : PR contains keyword retry listener

@Snooz82
Copy link
Member

Snooz82 commented Dec 2, 2025

@MarvKler

I did some refactoring, that you should merge into your branch.
https://github.com/MarketSquare/robotframework-retryfailed/tree/pr-14

This includes:

  • switching from setup.py to pyproject.toml,
  • introducing ruff and mypy
  • introducing pre-commit hooks
  • added typing to your code
  • added some other test cases with [Setup] and [Teardown] which do not work as expected.
  • added python keyword that can be retried 3 times and has a configurable failure index.

Please also see the comments in your code.
But fix them after you merge the branch to your repo

registered_retry_keyword.kw_lineno == kw_data.kw_lineno
):
return
self.retry_keywords.append(kw_data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this whole start_keyword basically does add a keyword to the list of keyword that can be retried.
Couldn't that just be done in the end_keyword?

Comment on lines +170 to +171
if self._original_log_level:
BuiltIn().set_log_level(self._original_log_level)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the log level only be decreased by the keyword that did increase it?
e.g. if a userkeyword has to be retried, all its called keywords should be executed on the elevated log level. This here seems to switch back to the original, after the first library keyword.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added code to reset log level only on failed / passed state by the keyword which has initially changed the log level

Comment on lines +173 to +185
match_kw_retry = False
kw_to_retry: KeywordMetaData
for index, kw in enumerate(self.retry_keywords):
if kw.kw_name != executed_kw_name or kw.kw_source != executed_kw_source:
continue
else:
match_kw_retry = True
current_index = index
kw_to_retry = kw

# If currently executed keyword does not match any defined RetryKeyword -> just return
if not match_kw_retry:
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that whole section seems to check if the keyword can be retried. But isn't that only relevant if the status is fail the first time?
Because on the second time, we should be sure already that we are currently retrying a keyword.
Also here, in the case we fail the first time, it would be the part, where we do all the code from start_keyword?!

…fixed some comments (#3)

* refactored to pyproject, flit, ruff, etc and added tests and typing

* merged pr-14 to fork, fixed some of the comments

---------

Co-authored-by: René <snooz@posteo.de>
Co-authored-by: Marvin Klerx <marvin.klerx@imbus.de>
@MarvKler
Copy link
Author

New strategy:

RetryKeyword:
  keyword: RunningKeyword
  remaining_retries: int

End Keyword 
if not _retries := _check_if_retry(keyword):
  return

If status != FAIL
  if retry_stack and retry_stack[-1].keyword == keyword) :
    keyword.doc += Passed on {retries - remaining} retries
    retry_stack.pop()
    if not retry_stack and not self.test_retries:
      Build().log_level = self._original_log_level
      self._original_log_level = None
  Return

if keyword.type in ("SETUP", "TEARDOWN"):
  keyword.msg += "SETUP and TEARDOWN can not be retried"
  return

if retry_stack and retry_stack[-1].keyword == keyword) : 
# wir sind im Stack an letzter Stelle
  if not retry_stack[-1].remaining_retries:
    retry_stack().pop()
    keyword.doc += Final Retry Failed message
    return
  retry_stack[-1].remaining_retries -= 1
else: 
#das ist die initiale detection eines Fehlers
  retry_stack.append(RetryKeyword(keyword, _retries)) 
  result.status = "NOT RUN"

keyword.doc  += Funky Message
keyword.parent.body.inser(keyword.parent.body.index(keyword), keyword)
if self.log_level:
  original = BuiltIn().log_level = self.log_level
  if not self._original_log_level:
    self._original_log_level = original

MarvKler and others added 3 commits March 2, 2026 17:02
* added state for ongoing kw retry

* strategy for discussions

* new strategy - draft

* fix retry count mechanism

* retry handling + log handling

* warn instead error

---------

Co-authored-by: Marvin Klerx <marvinklerx20@gmail.com>
Co-authored-by: Marvin Klerx <marvin@BREMBO.imbus.de>
@MarvKler
Copy link
Author

MarvKler commented Mar 2, 2026

@Snooz82 Please check the latest state of this PR - i have applied the new strategy discussed last week. Additionally, i have changed the initial loglevel handling a bit, but from my point of view this should match our expectation now.

PS: The RetryFailed listener seems to be working also after removing the end_suite listener function...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants