Skip to content

Commit

Permalink
feat: Clarify error message: "ValueError: Unknown or corrupt egg" ins…
Browse files Browse the repository at this point in the history
…tead of "TypeError: 'tuple' object is not an iterator", #282
  • Loading branch information
jpmckinney committed Jul 16, 2024
1 parent 616272c commit b229169
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 6 deletions.
6 changes: 5 additions & 1 deletion docs/news.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ API
^^^

- If the ``egg`` parameter to the :ref:`addversion.json`` webservice is not a ZIP file, use the error message, "egg is not a ZIP file (if using curl, use egg=@path not egg=path)".
- Clarify some error messages: for example, ``'project' parameter is required`` instead of ``'project'``, and ``exception class: message`` instead of ``message``.
- Clarify some error messages, for example:

- ``'project' parameter is required`` instead of ``'project'``
- ``exception class: message`` instead of ``message``
- ``ValueError: Unknown or corrupt egg`` instead of ``TypeError: 'tuple' object is not an iterator``

CLI
^^^
Expand Down
5 changes: 4 additions & 1 deletion scrapyd/eggutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ def activate_egg(eggpath):
to activate a Scrapy egg file. Don't use it from other code as it may
leave unwanted side effects.
"""
distributions = pkg_resources.find_distributions(eggpath)
if isinstance(distributions, tuple):
raise ValueError("Unknown or corrupt egg")
try:
d = next(pkg_resources.find_distributions(eggpath))
d = next(distributions)
except StopIteration:
raise ValueError("Unknown or corrupt egg")
d.activate()
Expand Down
4 changes: 4 additions & 0 deletions scrapyd/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ class ScrapydError(Exception):

class MissingRequiredArgument(ScrapydError):
"""Raised if a required argument is missing"""


class RunnerError(ScrapydError):
"""Raised if the runner returns an error code"""
3 changes: 2 additions & 1 deletion scrapyd/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from twisted.trial import unittest

from scrapyd import get_application
from scrapyd.exceptions import RunnerError
from scrapyd.interfaces import IEggStorage
from scrapyd.utils import UtilsCache, get_crawl_args, get_spider_list, sorted_versions

Expand Down Expand Up @@ -123,7 +124,7 @@ def popen_wrapper(*args, **kwargs):
return Popen(cmd, *args, **kwargs)

with mock.patch('scrapyd.utils.Popen', wraps=popen_wrapper):
exc = self.assertRaises(RuntimeError, get_spider_list, 'mybot3', pythonpath=pypath)
exc = self.assertRaises(RunnerError, get_spider_list, 'mybot3', pythonpath=pypath)
self.assertRegex(str(exc).rstrip(), r'Exception: This should break the `scrapy list` command$')


Expand Down
3 changes: 2 additions & 1 deletion scrapyd/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from twisted.web import resource

from scrapyd.config import Config
from scrapyd.exceptions import RunnerError
from scrapyd.sqlite import JsonSqliteDict


Expand Down Expand Up @@ -139,7 +140,7 @@ def get_spider_list(project, runner=None, pythonpath=None, version=''):
if proc.returncode:
msg = err or out or ''
msg = msg.decode('utf8')
raise RuntimeError(msg)
raise RunnerError(msg)
# FIXME: can we reliably decode as UTF-8?
# scrapy list does `print(list)`
tmp = out.decode('utf-8').splitlines()
Expand Down
5 changes: 3 additions & 2 deletions scrapyd/webservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ def render_POST(self, txrequest):
class AddVersion(WsResource):

def render_POST(self, txrequest):
eggf = BytesIO(_pop_required_param(txrequest.args, b'egg')[0])
if not zipfile.is_zipfile(eggf):
egg = _pop_required_param(txrequest.args, b'egg')[0]
if not zipfile.is_zipfile(BytesIO(egg)):
return {"status": "error", "message": "egg is not a ZIP file (if using curl, use egg=@path not egg=path)"}
eggf = BytesIO(egg)
args = native_stringify_dict(copy(txrequest.args), keys_only=False)
project = _get_required_param(args, 'project')[0]
version = _get_required_param(args, 'version')[0]
Expand Down

0 comments on commit b229169

Please sign in to comment.