Skip to content

Release #259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## [Unreleased]

## [5.6.4]
### Added
- `ErrorPrintingHttpRequest` and `ErrorPrintingAsyncHttpRequest` classes to avoid recursion on ReportPortal logging, by @HardNorth
### Removed
Expand Down
4 changes: 1 addition & 3 deletions reportportal_client/aio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,8 @@ async def finish_launch(
).make()
if not response:
return None
message = await response.message
logger.debug("finish_launch - ID: %s", await await_if_necessary(launch_uuid))
logger.debug("response message: %s", message)
return message
return None

async def update_test_item(
self,
Expand Down
6 changes: 1 addition & 5 deletions reportportal_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,12 +771,8 @@ def finish_launch(
if not response:
return None
logger.debug("finish_launch - ID: %s", self.__launch_uuid)
logger.debug("response message: %s", response.message)
message = response.message
else:
message = ""
self._log(self._log_batcher.flush())
return message
return None

def update_test_item(
self, item_uuid: str, attributes: Optional[Union[list, dict]] = None, description: Optional[str] = None
Expand Down
12 changes: 6 additions & 6 deletions reportportal_client/core/rp_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,20 @@ def make(self) -> Optional[RPResponse]:


class ErrorPrintingHttpRequest(HttpRequest):
"""This is specific request object which catches any request error and prints it to the "std.err".
"""This is specific request object which catches any request error and prints it to the "sys.stderr".

The object is supposed to be used in logging methods only to prevent infinite recursion of logging, when logging
framework configured to log everything to ReportPortal. In this case if a request to ReportPortal fails, the
failure will be logged to ReportPortal once again and, for example, in case of endpoint configuration error, it
will also fail and will be logged again. So, the recursion will never end.

This class is used to prevent this situation. It catches any request error and prints it to the "std.err".
This class is used to prevent this situation. It catches any request error and prints it to the "sys.stderr".
"""

def make(self) -> Optional[RPResponse]:
"""Make HTTP request to the ReportPortal API.

The method catches any request error and prints it to the "std.err".
The method catches any request error and prints it to the "sys.stderr".

:return: wrapped HTTP response or None in case of failure
"""
Expand Down Expand Up @@ -223,20 +223,20 @@ async def make(self) -> Optional[AsyncRPResponse]:


class ErrorPrintingAsyncHttpRequest(AsyncHttpRequest):
"""This is specific request object which catches any request error and prints it to the "std.err".
"""This is specific request object which catches any request error and prints it to the "sys.stderr".

The object is supposed to be used in logging methods only to prevent infinite recursion of logging, when logging
framework configured to log everything to ReportPortal. In this case if a request to ReportPortal fails, the
failure will be logged to ReportPortal once again and, for example, in case of endpoint configuration error, it
will also fail and will be logged again. So, the recursion will never end.

This class is used to prevent this situation. It catches any request error and prints it to the "std.err".
This class is used to prevent this situation. It catches any request error and prints it to the "sys.stderr".
"""

async def make(self) -> Optional[AsyncRPResponse]:
"""Asynchronously make HTTP request to the ReportPortal API.

The method catches any request error and prints it to the "std.err".
The method catches any request error and prints it to the "sys.stderr".

:return: wrapped HTTP response or None in case of failure
"""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from setuptools import find_packages, setup

__version__ = "5.6.4"
__version__ = "5.6.5"

TYPE_STUBS = ["*.pyi"]

Expand Down
4 changes: 2 additions & 2 deletions tests/aio/test_aio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ async def test_finish_launch(aio_client: Client):
attributes = {"attribute_key": "attribute_value", "system": False}

result = await aio_client.finish_launch(launch_uuid, end_time, status=status, attributes=attributes)
assert result == RESPONSE_MESSAGE
assert result is None
session.put.assert_called_once()
call_args = session.put.call_args_list[0]
assert expected_uri == call_args[0][0]
Expand All @@ -671,7 +671,7 @@ async def test_finish_launch_default_values(aio_client: Client):
end_time = str(1696921416000)

result = await aio_client.finish_launch(launch_uuid, end_time)
assert result == RESPONSE_MESSAGE
assert result is None
session.put.assert_called_once()
call_args = session.put.call_args_list[0]
assert expected_uri == call_args[0][0]
Expand Down
2 changes: 2 additions & 0 deletions tests/aio/test_threaded_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# limitations under the License

import pickle
import time
from unittest import mock

# noinspection PyPackageRequirements
Expand Down Expand Up @@ -46,6 +47,7 @@ def test_clone():
async_client = ThreadedRPClient(*args, **kwargs)
task1 = async_client.create_task(__empty_string())
task2 = async_client.create_task(__empty_string())
time.sleep(0.1)
task1.blocking_result()
task2.blocking_result()
async_client._add_current_item(task1)
Expand Down