mirror of
https://github.com/miurahr/aqtinstall.git
synced 2025-12-18 13:14:37 +03:00
Catch OSError(errno.ENOSPC) and PermissionError
When the destination drive is not writable or has insufficient space, these exceptions are raised during `run_installer`. Unless they are caught and dealt with, `aqtinstall` requests that the user file a bug report. This change catches these errors and prints a nice error message instead of requesting a bug report.
This commit is contained in:
@@ -102,3 +102,11 @@ class UpdaterError(AqtException):
|
|||||||
|
|
||||||
class OutOfMemory(AqtException):
|
class OutOfMemory(AqtException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class OutOfDiskSpace(AqtException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DiskAccessNotPermitted(AqtException):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import errno
|
||||||
import gc
|
import gc
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os
|
||||||
@@ -47,6 +48,8 @@ from aqt.exceptions import (
|
|||||||
ArchiveListError,
|
ArchiveListError,
|
||||||
CliInputError,
|
CliInputError,
|
||||||
CliKeyboardInterrupt,
|
CliKeyboardInterrupt,
|
||||||
|
DiskAccessNotPermitted,
|
||||||
|
OutOfDiskSpace,
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
)
|
)
|
||||||
from aqt.helper import (
|
from aqt.helper import (
|
||||||
@@ -1127,6 +1130,23 @@ def run_installer(archives: List[QtPackage], base_dir: str, sevenzip: Optional[s
|
|||||||
pool.starmap(installer, tasks)
|
pool.starmap(installer, tasks)
|
||||||
pool.close()
|
pool.close()
|
||||||
pool.join()
|
pool.join()
|
||||||
|
except PermissionError as e: # subclass of OSError
|
||||||
|
close_worker_pool_on_exception(e)
|
||||||
|
raise DiskAccessNotPermitted(
|
||||||
|
f"Failed to write to base directory at {base_dir}",
|
||||||
|
suggested_action=[
|
||||||
|
"Check that the destination is writable and does not already contain files owned by another user."
|
||||||
|
],
|
||||||
|
) from e
|
||||||
|
except OSError as e:
|
||||||
|
close_worker_pool_on_exception(e)
|
||||||
|
if e.errno == errno.ENOSPC:
|
||||||
|
raise OutOfDiskSpace(
|
||||||
|
"Insufficient disk space to complete installation.",
|
||||||
|
suggested_action=["Check available disk space.", "Check size requirements for installation."],
|
||||||
|
) from e
|
||||||
|
else:
|
||||||
|
raise
|
||||||
except KeyboardInterrupt as e:
|
except KeyboardInterrupt as e:
|
||||||
close_worker_pool_on_exception(e)
|
close_worker_pool_on_exception(e)
|
||||||
raise CliKeyboardInterrupt("Installer halted by keyboard interrupt.") from e
|
raise CliKeyboardInterrupt("Installer halted by keyboard interrupt.") from e
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import errno
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@@ -1156,10 +1157,10 @@ def test_install_nonexistent_archives(monkeypatch, capsys, cmd, xml_file: Option
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"exception_class, settings_file, expect_end_msg, expect_return",
|
"exception, settings_file, expect_end_msg, expect_return",
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
RuntimeError,
|
RuntimeError(),
|
||||||
"../aqt/settings.ini",
|
"../aqt/settings.ini",
|
||||||
"===========================PLEASE FILE A BUG REPORT===========================\n"
|
"===========================PLEASE FILE A BUG REPORT===========================\n"
|
||||||
"You have discovered a bug in aqt.\n"
|
"You have discovered a bug in aqt.\n"
|
||||||
@@ -1168,14 +1169,14 @@ def test_install_nonexistent_archives(monkeypatch, capsys, cmd, xml_file: Option
|
|||||||
Cli.UNHANDLED_EXCEPTION_CODE,
|
Cli.UNHANDLED_EXCEPTION_CODE,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
KeyboardInterrupt,
|
KeyboardInterrupt(),
|
||||||
"../aqt/settings.ini",
|
"../aqt/settings.ini",
|
||||||
"WARNING : Caught KeyboardInterrupt, terminating installer workers\n"
|
"WARNING : Caught KeyboardInterrupt, terminating installer workers\n"
|
||||||
"ERROR : Installer halted by keyboard interrupt.",
|
"ERROR : Installer halted by keyboard interrupt.",
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
MemoryError,
|
MemoryError(),
|
||||||
"../aqt/settings.ini",
|
"../aqt/settings.ini",
|
||||||
"WARNING : Caught MemoryError, terminating installer workers\n"
|
"WARNING : Caught MemoryError, terminating installer workers\n"
|
||||||
"ERROR : Out of memory when downloading and extracting archives in parallel.\n"
|
"ERROR : Out of memory when downloading and extracting archives in parallel.\n"
|
||||||
@@ -1187,7 +1188,7 @@ def test_install_nonexistent_archives(monkeypatch, capsys, cmd, xml_file: Option
|
|||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
MemoryError,
|
MemoryError(),
|
||||||
"data/settings_no_concurrency.ini",
|
"data/settings_no_concurrency.ini",
|
||||||
"WARNING : Caught MemoryError, terminating installer workers\n"
|
"WARNING : Caught MemoryError, terminating installer workers\n"
|
||||||
"ERROR : Out of memory when downloading and extracting archives.\n"
|
"ERROR : Out of memory when downloading and extracting archives.\n"
|
||||||
@@ -1197,11 +1198,30 @@ def test_install_nonexistent_archives(monkeypatch, capsys, cmd, xml_file: Option
|
|||||||
"(see https://aqtinstall.readthedocs.io/en/latest/cli.html#cmdoption-list-tool-external)",
|
"(see https://aqtinstall.readthedocs.io/en/latest/cli.html#cmdoption-list-tool-external)",
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
OSError(errno.ENOSPC, "No space left on device"),
|
||||||
|
"../aqt/settings.ini",
|
||||||
|
"WARNING : Caught OSError, terminating installer workers\n"
|
||||||
|
"ERROR : Insufficient disk space to complete installation.\n"
|
||||||
|
"==============================Suggested follow-up:==============================\n"
|
||||||
|
"* Check available disk space.\n"
|
||||||
|
"* Check size requirements for installation.",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
PermissionError(),
|
||||||
|
"../aqt/settings.ini",
|
||||||
|
"WARNING : Caught PermissionError, terminating installer workers\n"
|
||||||
|
f"ERROR : Failed to write to base directory at {os.getcwd()}\n"
|
||||||
|
"==============================Suggested follow-up:==============================\n"
|
||||||
|
"* Check that the destination is writable and does not already contain files owned by another user.",
|
||||||
|
1,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_install_pool_exception(monkeypatch, capsys, exception_class, settings_file, expect_end_msg, expect_return):
|
def test_install_pool_exception(monkeypatch, capsys, exception, settings_file, expect_end_msg, expect_return):
|
||||||
def mock_installer_func(*args):
|
def mock_installer_func(*args):
|
||||||
raise exception_class()
|
raise exception
|
||||||
|
|
||||||
host, target, ver, arch = "windows", "desktop", "6.1.0", "win64_mingw81"
|
host, target, ver, arch = "windows", "desktop", "6.1.0", "win64_mingw81"
|
||||||
updates_url = "windows_x86/desktop/qt6_610/Updates.xml"
|
updates_url = "windows_x86/desktop/qt6_610/Updates.xml"
|
||||||
|
|||||||
Reference in New Issue
Block a user