Skip to content

Commit

Permalink
rework channel error messaging
Browse files Browse the repository at this point in the history
Signed-off-by: Kale Franz <[email protected]>
  • Loading branch information
kalefranz committed Jul 6, 2018
1 parent 1cfdaf7 commit 968edad
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 46 deletions.
8 changes: 2 additions & 6 deletions conda/core/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ..base.context import context
from ..common.compat import itervalues
from ..common.io import ThreadLimitedThreadPoolExecutor, as_completed, time_recorder
from ..exceptions import OperationNotAllowed
from ..exceptions import OperationNotAllowed, ChannelNotAllowed
from ..models.channel import Channel, all_channel_urls
from ..models.match_spec import MatchSpec
from ..models.records import EMPTY_LINK, PackageCacheRecord, PrefixRecord
Expand All @@ -35,11 +35,7 @@ def check_whitelist(channel_urls):
for url in channel_urls:
these_urls = Channel(url).base_urls
if not all(this_url in whitelist_channel_urls for this_url in these_urls):
bad_channel = Channel(url)
raise OperationNotAllowed("Channel not included in whitelist:\n"
" location: %s\n"
" canonical name: %s\n"
% (bad_channel.location, bad_channel.canonical_name))
raise ChannelNotAllowed(Channel(url))


LAST_CHANNEL_URLS = []
Expand Down
39 changes: 6 additions & 33 deletions conda/core/subdir_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
from ..common.io import ThreadLimitedThreadPoolExecutor, as_completed
from ..common.url import join_url, maybe_unquote
from ..core.package_cache_data import PackageCacheData
from ..exceptions import CondaDependencyError, CondaHTTPError, NotWritableError
from ..exceptions import CondaDependencyError, CondaHTTPError, NotWritableError, \
InvalidUnavailableChannel
from ..gateways.connection import (ConnectionError, HTTPError, InsecureRequestWarning,
InvalidSchema, SSLError)
from ..gateways.connection.session import CondaSession
Expand Down Expand Up @@ -426,43 +427,15 @@ def fetch_repodata_remote_request(url, etag, mod_stamp):
status_code = getattr(e.response, 'status_code', None)
if status_code in (403, 404):
if not url.endswith('/noarch'):
log.info("Unable to retrieve repodata (%d error) for %s", status_code, url)
return None
else:
if context.allow_non_channel_urls:
help_message = dedent("""
WARNING: The remote server could not find the noarch directory for the
requested channel with url: %s
It is possible you have given conda an invalid channel. Please double-check
your conda configuration using `conda config --show channels`.
If the requested url is in fact a valid conda channel, please request that the
channel administrator create `noarch/repodata.json` and associated
`noarch/repodata.json.bz2` files, even if `noarch/repodata.json` is empty.
$ mkdir noarch
$ echo '{}' > noarch/repodata.json
$ bzip2 -k noarch/repodata.json
""") % maybe_unquote(dirname(url))
stderrlog.warn(help_message)
stderrlog.warning("Unable to retrieve repodata (%d error) for %s",
status_code, url)
return None
else:
help_message = dals("""
The remote server could not find the noarch directory for the
requested channel with url: %s
As of conda 4.3, a valid channel must contain a `noarch/repodata.json` and
associated `noarch/repodata.json.bz2` file, even if `noarch/repodata.json` is
empty. please request that the channel administrator create
`noarch/repodata.json` and associated `noarch/repodata.json.bz2` files.
$ mkdir noarch
$ echo '{}' > noarch/repodata.json
$ bzip2 -k noarch/repodata.json
You will need to adjust your conda configuration to proceed.
Use `conda config --show channels` to view your configuration's current state.
Further configuration help can be found at <%s>.
""") % (maybe_unquote(dirname(url)),
join_url(CONDA_HOMEPAGE_URL, 'docs/config.html'))
raise InvalidUnavailableChannel(Channel(dirname(url)), status_code)

elif status_code == 401:
channel = Channel(url)
Expand Down
56 changes: 49 additions & 7 deletions conda/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from .common.compat import PY2, ensure_text_type, input, iteritems, iterkeys, on_win, string_types
from .common.io import dashlist, timeout
from .common.signals import get_signal_name
from .common.url import maybe_unquote

try:
from cytoolz.itertoolz import groupby
Expand Down Expand Up @@ -412,15 +411,56 @@ def __init__(self, key, message, *args):


class ChannelError(CondaError):
def __init__(self, message, *args):
msg = '%s' % message
super(ChannelError, self).__init__(msg)
pass


class ChannelNotAllowed(ChannelError):
def __init__(self, message, *args):
msg = '%s' % message
super(ChannelNotAllowed, self).__init__(msg, *args)
def __init__(self, channel):
from .models.channel import Channel
from .common.url import maybe_unquote
channel = Channel(channel)
channel_name = channel.name
channel_url = maybe_unquote(channel.url(with_credentials=False))
message = dals("""
Channel not included in whitelist:
channel name: %(channel_name)s
channel url: %(channel_url)s
""")
super(ChannelNotAllowed, self).__init__(message, channel_url=channel_url,
channel_name=channel_name)


class InvalidUnavailableChannel(ChannelError):

def __init__(self, channel, http_error_code):
from .models.channel import Channel
from .common.url import join_url, maybe_unquote
channel = Channel(channel)
channel_name = channel.name
channel_url = maybe_unquote(channel.url(with_credentials=False))
message = dals("""
Invalid or unavailable channel:
channel name: %(channel_name)s
channel url: %(channel_url)s
HTTP error: %(http_error_code)d
You will need to adjust your conda configuration to proceed.
Use `conda config --show channels` to view your configuration's current state,
and use `conda config --show-sources` to view config file locations.
""")

if channel.scheme == 'file':
message += dals("""
As of conda 4.3, a valid channel must contain a `noarch/repodata.json` and
associated `noarch/repodata.json.bz2` file, even if `noarch/repodata.json` is
empty. Use `conda index %s`, or create `noarch/repodata.json`
and associated `noarch/repodata.json.bz2`.
""") % join_url(channel.location, channel.name)

super(InvalidUnavailableChannel, self).__init__(message, channel_url=channel_url,
channel_name=channel_name,
http_error_code=http_error_code)


class OperationNotAllowed(CondaError):
Expand Down Expand Up @@ -456,6 +496,7 @@ def __init__(self, url, target_full_path, expected_md5sum, actual_md5sum):
expected md5 sum: %(expected_md5sum)s
actual md5 sum: %(actual_md5sum)s
""")
from .common.url import maybe_unquote
url = maybe_unquote(url)
super(MD5MismatchError, self).__init__(message, url=url, target_full_path=target_full_path,
expected_md5sum=expected_md5sum,
Expand All @@ -477,6 +518,7 @@ def __init__(self, prefix, package_name):
class CondaHTTPError(CondaError):
def __init__(self, message, url, status_code, reason, elapsed_time, response=None,
caused_by=None):
from .common.url import maybe_unquote
_message = dals("""
HTTP %(status_code)s %(reason)s for url <%(url)s>
Elapsed: %(elapsed_time)s
Expand Down

0 comments on commit 968edad

Please sign in to comment.