Manually handle out of storage and JPEG too big errors
This commit is contained in:
parent
9ab5a461c0
commit
f6ae4807ff
1 changed files with 48 additions and 18 deletions
|
|
@ -268,30 +268,51 @@ class FinalStitcher(BaseStitcher):
|
||||||
raise RuntimeError("stdout pipe was not created")
|
raise RuntimeError("stdout pipe was not created")
|
||||||
# Stop opening pipe blocking writing to it
|
# Stop opening pipe blocking writing to it
|
||||||
os.set_blocking(process.stdout.fileno(), False)
|
os.set_blocking(process.stdout.fileno(), False)
|
||||||
|
output_lines = self._log_ongoing(process)
|
||||||
|
returncode = process.wait()
|
||||||
|
full_output = "".join(output_lines)
|
||||||
|
|
||||||
self._log_ongoing(process)
|
if returncode == 0:
|
||||||
|
|
||||||
if process.poll() == 0:
|
|
||||||
self.logger.info("Stitching complete")
|
self.logger.info("Stitching complete")
|
||||||
elif process.poll() == -9:
|
|
||||||
|
elif returncode == -9:
|
||||||
raise ExternalSigkillError(
|
raise ExternalSigkillError(
|
||||||
"Stitching was killed by an external process. This is "
|
"Stitching was killed by an external process. "
|
||||||
"most likely due to running out of memory."
|
"Most likely due to running out of memory."
|
||||||
|
)
|
||||||
|
|
||||||
|
elif returncode == 1:
|
||||||
|
if "No space left on device" in full_output or "Errno 28" in full_output:
|
||||||
|
raise ChildProcessError(
|
||||||
|
"Not enough space on disk to stitch. Please delete some scans or increase your storage size."
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
"Maximum supported image dimension" in full_output
|
||||||
|
or "OSError: broken data stream when writing image file" in full_output
|
||||||
|
):
|
||||||
|
raise ChildProcessError(
|
||||||
|
"Scan too big for stitching into a JPEG file. Download the full scan and stitch with alternate settings."
|
||||||
|
)
|
||||||
|
raise ChildProcessError(
|
||||||
|
"Stitching errored with exit code 1.\nCheck the logs for more information."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ChildProcessError(
|
raise ChildProcessError(
|
||||||
f"Subprocess {STITCHING_CMD} errored with exit code {process.poll()}."
|
f"Stitching errored with exit code {returncode}.\nCheck the logs for more information."
|
||||||
)
|
)
|
||||||
|
|
||||||
def _log_ongoing(self, process: subprocess.Popen[str]) -> None:
|
def _log_ongoing(self, process: subprocess.Popen[str]) -> list[str]:
|
||||||
"""Log the ongoing process unless it is cancelled."""
|
"""Log the ongoing process unless it is cancelled.
|
||||||
|
|
||||||
|
:returns: a list of all lines
|
||||||
|
"""
|
||||||
if process.stdout is None: # pragma: no cover - impossible with stdout=PIPE
|
if process.stdout is None: # pragma: no cover - impossible with stdout=PIPE
|
||||||
raise RuntimeError("stdout pipe was not created")
|
raise RuntimeError("stdout pipe was not created")
|
||||||
|
|
||||||
|
output_lines: list[str] = []
|
||||||
# Poll returns None while running, will return the error code when finished
|
# Poll returns None while running, will return the error code when finished
|
||||||
while process.poll() is None:
|
while process.poll() is None:
|
||||||
self.log_buffer(process.stdout)
|
output_lines.extend(self.log_buffer(process.stdout))
|
||||||
# Once buffer is clear sleep for 0.2s before trying again.
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# This should act exactly like sleep if not started in a LabThings
|
# This should act exactly like sleep if not started in a LabThings
|
||||||
|
|
@ -304,11 +325,20 @@ class FinalStitcher(BaseStitcher):
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
# Print everything in the buffer when program finishes
|
# Print everything in the buffer when program finishes
|
||||||
self.log_buffer(process.stdout)
|
output_lines.extend(self.log_buffer(process.stdout))
|
||||||
|
|
||||||
def log_buffer(self, buffer: IO[str]) -> None:
|
return output_lines
|
||||||
"""Log everything in the buffer at INFO level."""
|
|
||||||
# Use rstrip to remove newlines from each line, as logging provides its own
|
def log_buffer(self, buffer: IO[str]) -> list[str]:
|
||||||
# new lines
|
"""Log everything currently available in the buffer and return lines."""
|
||||||
while line := buffer.readline():
|
lines: list[str] = []
|
||||||
self.logger.info(line.rstrip())
|
|
||||||
|
while True:
|
||||||
|
line = buffer.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
clean = line.rstrip()
|
||||||
|
self.logger.info(clean)
|
||||||
|
lines.append(line)
|
||||||
|
|
||||||
|
return lines
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue