aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/utils/snekbox/_cog.py8
-rw-r--r--bot/exts/utils/snekbox/_eval.py77
2 files changed, 58 insertions, 27 deletions
diff --git a/bot/exts/utils/snekbox/_cog.py b/bot/exts/utils/snekbox/_cog.py
index f8ddbbf0e..6aa7c6324 100644
--- a/bot/exts/utils/snekbox/_cog.py
+++ b/bot/exts/utils/snekbox/_cog.py
@@ -278,7 +278,9 @@ class Snekbox(Cog):
"""
async with ctx.typing():
result = await self.post_job(job)
- msg, error = result.get_message(job)
+ msg = result.get_message(job)
+ error = result.error_message
+ files_error = result.files_error_message
if error:
output, paste_link = error, None
@@ -293,6 +295,10 @@ class Snekbox(Cog):
if paste_link:
msg += f"Full output: {paste_link}"
+ # Additional files error message after output
+ if files_error:
+ msg += f"\n{files_error}"
+
# Collect stats of job fails + successes
if result.returncode != 0:
self.bot.stats.incr("snekbox.python.fail")
diff --git a/bot/exts/utils/snekbox/_eval.py b/bot/exts/utils/snekbox/_eval.py
index d955d26d0..748b58a3b 100644
--- a/bot/exts/utils/snekbox/_eval.py
+++ b/bot/exts/utils/snekbox/_eval.py
@@ -70,41 +70,66 @@ class EvalResult:
else: # Exception
return ":x:"
- def get_message(self, job: EvalJob) -> tuple[str, str]:
- """Return a user-friendly message and error corresponding to the process's return code."""
- msg = f"Your {job.version} {job.name} job has completed with return code {self.returncode}"
+ @property
+ def error_message(self) -> str:
+ """Return an error message corresponding to the process's return code."""
error = ""
-
if self.returncode is None:
- msg = f"Your {job.version} {job.name} job has failed"
error = self.stdout.strip()
- elif self.returncode == 128 + SIGKILL:
- msg = f"Your {job.version} {job.name} job timed out or ran out of memory"
elif self.returncode == 255:
- msg = f"Your {job.version} {job.name} job has failed"
error = "A fatal NsJail error occurred"
+ return error
+
+ @property
+ def files_error_message(self) -> str:
+ """Return an error message corresponding to the failed files."""
+ if not self.failed_files:
+ return ""
+
+ failed_files = f"({self.failed_files_str()})"
+
+ n_failed = len(self.failed_files)
+ files = f"file{'s' if n_failed > 1 else ''}"
+ msg = f"Failed to upload {n_failed} {files} {failed_files}"
+
+ if (n_failed + len(self.files)) > FILE_COUNT_LIMIT:
+ it_they = "they" if n_failed > 1 else "it"
+ msg += f" as {it_they} exceeded the {FILE_COUNT_LIMIT} file limit."
+ else:
+ msg += f". File sizes should each not exceed {sizeof_fmt(FILE_SIZE_LIMIT)}."
+
+ return msg
+
+ def failed_files_str(self, char_max: int = 85, file_max: int = 5) -> str:
+ """Return a string containing the names of failed files, truncated to lower of char_max and file_max."""
+ names = []
+ for file in self.failed_files:
+ char_max -= len(file)
+ if char_max <= 0 or len(names) >= file_max:
+ names.append("...")
+ break
+ names.append(file)
+ text = ", ".join(names)
+ return text
+
+ def get_message(self, job: EvalJob) -> str:
+ """Return a user-friendly message corresponding to the process's return code."""
+ msg = f"Your {job.version} {job.name} job"
+
+ if self.returncode is None:
+ msg += " has failed"
+ elif self.returncode == 128 + SIGKILL:
+ msg += " timed out or ran out of memory"
+ elif self.returncode == 255:
+ msg += " has failed"
else:
+ msg += f" has completed with return code {self.returncode}"
# Try to append signal's name if one exists
with contextlib.suppress(ValueError):
name = Signals(self.returncode - 128).name
- msg = f"{msg} ({name})"
-
- # Add error message for failed attachments
- if self.failed_files:
- failed_files = f"({', '.join(self.failed_files)})"
- # Case for over 10
- if len(self.failed_files) + len(self.files) > FILE_COUNT_LIMIT:
- msg += (
- f".\n\n> Some files were not able to be uploaded, as they exceeded"
- f" the {FILE_COUNT_LIMIT} file upload limit {failed_files}"
- )
- else:
- msg += (
- f".\n\n> Some files were not able to be uploaded {failed_files}."
- f" Check that the file size is less than {sizeof_fmt(FILE_SIZE_LIMIT)}"
- )
-
- return msg, error
+ msg += f" ({name})"
+
+ return msg
@classmethod
def from_dict(cls, data: dict[str, str | int | list[dict[str, str]]]) -> EvalResult: