1# This program is free software; you can redistribute it and/or modify
2# it under the terms of the GNU General Public License as published by
3# the Free Software Foundation; either version 2 of the License, or
4# (at your option) any later version.
5#
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9# GNU Library General Public License for more details.
10#
11# You should have received a copy of the GNU General Public License
12# along with this program; if not, write to the Free Software
13# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14# Copyright 2004 Duke University
15
16"""
17Core DNF Errors.
18"""
19
20from __future__ import unicode_literals
21from dnf.i18n import ucd, _, P_
22import dnf.util
23import libdnf
24import warnings
25
26class DeprecationWarning(DeprecationWarning):
27    # :api
28    pass
29
30
31class Error(Exception):
32    # :api
33    """Base Error. All other Errors thrown by DNF should inherit from this.
34
35    :api
36
37    """
38    def __init__(self, value=None):
39        super(Error, self).__init__()
40        self.value = None if value is None else ucd(value)
41
42    def __str__(self):
43        return "{}".format(self.value)
44
45    def __unicode__(self):
46        return ucd(self.__str__())
47
48
49
50class CompsError(Error):
51    # :api
52    pass
53
54
55class ConfigError(Error):
56    def __init__(self, value=None, raw_error=None):
57        super(ConfigError, self).__init__(value)
58        self.raw_error = ucd(raw_error) if raw_error is not None else None
59
60
61class DatabaseError(Error):
62    pass
63
64
65class DepsolveError(Error):
66    # :api
67    pass
68
69
70class DownloadError(Error):
71    # :api
72    def __init__(self, errmap):
73        super(DownloadError, self).__init__()
74        self.errmap = errmap
75
76    @staticmethod
77    def errmap2str(errmap):
78        errstrings = []
79        for key in errmap:
80            for error in errmap[key]:
81                msg = '%s: %s' % (key, error) if key else '%s' % error
82                errstrings.append(msg)
83        return '\n'.join(errstrings)
84
85    def __str__(self):
86        return self.errmap2str(self.errmap)
87
88
89class LockError(Error):
90    pass
91
92
93class MarkingError(Error):
94    # :api
95
96    def __init__(self, value=None, pkg_spec=None):
97        """Initialize the marking error instance."""
98        super(MarkingError, self).__init__(value)
99        self.pkg_spec = None if pkg_spec is None else ucd(pkg_spec)
100
101    def __str__(self):
102        string = super(MarkingError, self).__str__()
103        if self.pkg_spec:
104            string += ': ' + self.pkg_spec
105        return string
106
107
108class MarkingErrors(Error):
109    # :api
110    def __init__(self, no_match_group_specs=(), error_group_specs=(), no_match_pkg_specs=(),
111                 error_pkg_specs=(), module_depsolv_errors=()):
112        """Initialize the marking error instance."""
113        msg = _("Problems in request:")
114        if (no_match_pkg_specs):
115            msg += "\n" + _("missing packages: ") + ", ".join(no_match_pkg_specs)
116        if (error_pkg_specs):
117            msg += "\n" + _("broken packages: ") + ", ".join(error_pkg_specs)
118        if (no_match_group_specs):
119            msg += "\n" + _("missing groups or modules: ") + ", ".join(no_match_group_specs)
120        if (error_group_specs):
121            msg += "\n" + _("broken groups or modules: ") + ", ".join(error_group_specs)
122        if (module_depsolv_errors):
123            msg_mod = dnf.util._format_resolve_problems(module_depsolv_errors[0])
124            if module_depsolv_errors[1] == \
125                    libdnf.module.ModulePackageContainer.ModuleErrorType_ERROR_IN_DEFAULTS:
126                msg += "\n" + "\n".join([P_('Modular dependency problem with Defaults:',
127                                            'Modular dependency problems with Defaults:',
128                                            len(module_depsolv_errors)),
129                                        msg_mod])
130            else:
131                msg += "\n" + "\n".join([P_('Modular dependency problem:',
132                                            'Modular dependency problems:',
133                                            len(module_depsolv_errors)),
134                                        msg_mod])
135        super(MarkingErrors, self).__init__(msg)
136        self.no_match_group_specs = no_match_group_specs
137        self.error_group_specs = error_group_specs
138        self.no_match_pkg_specs = no_match_pkg_specs
139        self.error_pkg_specs = error_pkg_specs
140        self.module_depsolv_errors = module_depsolv_errors
141
142    @property
143    def module_debsolv_errors(self):
144        msg = "Attribute module_debsolv_errors is deprecated. Use module_depsolv_errors " \
145              "attribute instead."
146        warnings.warn(msg, DeprecationWarning, stacklevel=2)
147        return self.module_depsolv_errors
148
149class MetadataError(Error):
150    pass
151
152
153class MiscError(Error):
154    pass
155
156
157class PackagesNotAvailableError(MarkingError):
158    def __init__(self, value=None, pkg_spec=None, packages=None):
159        super(PackagesNotAvailableError, self).__init__(value, pkg_spec)
160        self.packages = packages or []
161
162
163class PackageNotFoundError(MarkingError):
164    pass
165
166
167class PackagesNotInstalledError(MarkingError):
168    def __init__(self, value=None, pkg_spec=None, packages=None):
169        super(PackagesNotInstalledError, self).__init__(value, pkg_spec)
170        self.packages = packages or []
171
172
173class ProcessLockError(LockError):
174    def __init__(self, value, pid):
175        super(ProcessLockError, self).__init__(value)
176        self.pid = pid
177
178    def __reduce__(self):
179        """Pickling support."""
180        return (ProcessLockError, (self.value, self.pid))
181
182
183class RepoError(Error):
184    # :api
185    pass
186
187
188class ThreadLockError(LockError):
189    pass
190
191
192class TransactionCheckError(Error):
193    pass
194