Skip to content

Commit 96e17d9

Browse files
committed
log error
1 parent ca739a6 commit 96e17d9

5 files changed

Lines changed: 84 additions & 1 deletion

File tree

src/pysonar_scanner/__main__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from pysonar_scanner import app_logging
2222
from pysonar_scanner import cache
23+
from pysonar_scanner import exceptions
2324
from pysonar_scanner.api import get_base_urls, SonarQubeApi, BaseUrls, MIN_SUPPORTED_SQ_VERSION
2425
from pysonar_scanner.configuration import configuration_loader
2526
from pysonar_scanner.configuration.configuration_loader import ConfigurationLoader
@@ -39,6 +40,13 @@
3940

4041

4142
def scan():
43+
try:
44+
return do_scan()
45+
except Exception as e:
46+
return exceptions.log_error(e)
47+
48+
49+
def do_scan():
4250
app_logging.setup()
4351

4452
config = ConfigurationLoader.load()

src/pysonar_scanner/exceptions.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from dataclasses import dataclass
2323
import logging
2424

25+
EXCEPTION_RETURN_CODE = 1
26+
2527

2628
@dataclass
2729
class MissingProperty:
@@ -66,3 +68,12 @@ class NoJreAvailableException(JreProvisioningException):
6668

6769
class UnsupportedArchiveFormat(JreProvisioningException):
6870
pass
71+
72+
73+
def log_error(e: Exception):
74+
logger = logging.getLogger()
75+
is_debug_level = logger.getEffectiveLevel() <= logging.DEBUG
76+
77+
logger.error(str(e), exc_info=is_debug_level)
78+
79+
return EXCEPTION_RETURN_CODE

tests/its/test_minimal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ def test_minimal_project_unexpected_arg(cli: CliClient):
4848
def test_invalid_token(sonarqube_client: SonarQubeClient, cli: CliClient):
4949
process = cli.run_analysis(sources_dir="minimal", token="invalid")
5050
assert process.returncode == 1, str(process.stdout)
51-
assert "401 Client Error" in process.stdout
51+
assert "Error while fetching the analysis version" in process.stdout

tests/unit/test_exceptions.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#
2+
# Sonar Scanner Python
3+
# Copyright (C) 2011-2024 SonarSource SA.
4+
# mailto:info AT sonarsource DOT com
5+
#
6+
# This program is free software; you can redistribute it and/or
7+
# modify it under the terms of the GNU Lesser General Public
8+
# License as published by the Free Software Foundation; either
9+
# version 3 of the License, or (at your option) any later version.
10+
# This program is distributed in the hope that it will be useful,
11+
#
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with this program; if not, write to the Free Software Foundation,
18+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
#
20+
import pytest
21+
import unittest
22+
import logging
23+
from pysonar_scanner.exceptions import log_error, EXCEPTION_RETURN_CODE
24+
25+
26+
class TestExceptions(unittest.TestCase):
27+
@pytest.fixture(autouse=True)
28+
def set_caplog(self, caplog: pytest.LogCaptureFixture):
29+
self.caplog = caplog
30+
31+
def test_log_error_returns_exception_return_code(self):
32+
exception = Exception("Test exception")
33+
result = log_error(exception)
34+
self.assertEqual(result, EXCEPTION_RETURN_CODE)
35+
36+
def setUp(self) -> None:
37+
self.caplog.clear()
38+
39+
def test_log_error_logs_message(self):
40+
# Test that log_error logs the exception message
41+
exception = Exception("Test exception")
42+
with self.caplog.at_level(logging.ERROR):
43+
log_error(exception)
44+
45+
self.assertIn("Test exception", self.caplog.text)
46+
self.assertNotIn("Traceback", self.caplog.text)
47+
48+
def test_log_error_includes_stack_trace_in_debug_mode(self):
49+
# raises an exception to get an Exception object with a strace trace
50+
try:
51+
raise Exception("Test exception")
52+
except Exception as exception:
53+
with self.caplog.at_level(logging.DEBUG):
54+
log_error(exception)
55+
56+
self.assertIn("Test exception", self.caplog.text)
57+
self.assertIn("Traceback", self.caplog.text)

tests/unit/test_main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ def test_minimal_success_run(self, run_mock, create_jre_mock, provision_mock, lo
8484

8585
self.assertEqual(expected_config, config)
8686

87+
@patch.object(ConfigurationLoader, "load")
88+
def test_scan_with_exception(self, load_mock):
89+
load_mock.side_effect = Exception("Test exception")
90+
91+
exitcode = scan()
92+
self.assertEqual(1, exitcode)
93+
8794
def test_version_check_outdated_sonarqube(self):
8895
sq_cloud_api = sq_api_utils.get_sq_server()
8996
sq_cloud_api.get_analysis_version = Mock(return_value=SQVersion.from_str("9.9.9"))

0 commit comments

Comments
 (0)