Test Failed
Push — master ( fcf1be...4a2af5 )
by Heiko 'riot'
04:20
created

isomer.error.abort()   B

Complexity

Conditions 6

Size

Total Lines 37
Code Lines 26

Duplication

Lines 19
Ratio 51.35 %

Importance

Changes 0
Metric Value
cc 6
eloc 26
nop 2
dl 19
loc 37
rs 8.3226
c 0
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: UTF-8 -*-
3
4
# Isomer - The distributed application framework
5
# ==============================================
6
# Copyright (C) 2011-2020 Heiko 'riot' Weinen <[email protected]> and others.
7
#
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU Affero General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU Affero General Public License for more details.
17
#
18
# You should have received a copy of the GNU Affero General Public License
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
"""
22
23
24
Module: Error
25
=============
26
27
Error handling
28
29
30
"""
31
32
import sys
33
34
from isomer.logger import isolog, critical
35
36
37
def log(*args, **kwargs):
38
    """Log as previous emitter"""
39
    kwargs.update({"frame_ref": 2})
40
    kwargs["lvl"] = critical
41
    if "emitter" not in kwargs:
42
        kwargs["emitter"] = "MANAGE"
43
    isolog(*args, **kwargs)
44
45
46
# TODO:
47
#  * Categorize error codes into groups
48
#  * Enumerate codes
49
#  * Find all calls to abort and fix them up
50
51
INSTALL_MESSAGE = 'Please run "python3 setup.py install" first.\n' \
52
                  'If you get an error about setuptools, install python3 setuptools ' \
53
                  'for your distribution.\n\nFor more information, please read the ' \
54
                  'manual installation instructions:\n' \
55
                  'https://isomer.readthedocs.io/en/latest/start/installing.html#manual'
56
57
EXIT_INVALID_ENVIRONMENT = {"code": 1, "message": ""}
58
EXIT_INVALID_CONFIGURATION = {"code": 2, "message": ""}
59
EXIT_INVALID_INTERPRETER = {
60
    "code": 10,
61
    "message": "Invalid Python interpreter used. Isomer is not compatible with Python < 3.6!"
62
}
63
EXIT_CANNOT_IMPORT_INSTALLER = {"code": 11, "message": "Cannot import Isomer installer tool.\n" + INSTALL_MESSAGE}
64
EXIT_CANNOT_IMPORT_TOOL = {
65
    "code": 11,
66
    "message": "Cannot import Isomer tool.\nYou could inspect the problem by "
67
               "invoking the development tester:\n   python3 dev/isotest.py\n"
68
               "to get at the full error.\n\n" + INSTALL_MESSAGE
69
}
70
EXIT_NO_CONFIGURATION = {"code": 61, "message": ""}
71
EXIT_NOT_OVERWRITING_CONFIGURATION = {
72
    "code": 52,
73
    "message": "Configuration directory exists, not overwriting!",
74
}
75
76
EXIT_INVALID_SOURCE = {
77
    "code": 3,
78
    "message": "Only installing from github or local is currently supported",
79
}
80
EXIT_ROOT_REQUIRED = {"code": 4, "message": "Need root access to install. Use sudo."}
81
EXIT_NO_PERMISSION = {"code": 5, "message": "No permission. Maybe use sudo?"}
82
EXIT_FRONTEND_BUILD_FAILED = {"code": 6, "message": "Frontend was not built."}
83
EXIT_INSTALLATION_FAILED = {
84
    "code": 11,
85
    "message": "Installation failed. Check logs and/or increase logging via "
86
               "--clog/--flog",
87
}
88
EXIT_PROVISIONING_FAILED = {"code": 12, "message": "Could not provision required data."}
89
EXIT_INSTANCE_EXISTS = {"code": 21, "message": "Instance already exists"}
90
EXIT_INSTANCE_UNKNOWN = {"code": 22, "message": ""}
91
EXIT_SERVICE_INVALID = {"code": 31, "message": ""}
92
EXIT_USER_BAILED_OUT = {"code": 41, "message": ""}
93
EXIT_NOTHING_TO_ARCHIVE = {"code": 51, "message": ""}
94
95
EXIT_INVALID_PARAMETER = {
96
    "code": 62,
97
    "message": "Invalid instance configuration parameter specified",
98
}
99
EXIT_INVALID_VALUE = {
100
    "code": 64,
101
    "message": "Invalid instance configuration value specified",
102
}
103
EXIT_NO_CERTIFICATE = {"code": 63, "message": ""}
104
EXIT_NO_DATABASE = {"code": 50020, "message": "No database is available"}
105
EXIT_NO_DATABASE_DEFINED = {
106
    "code": 50021,
107
    "message": "No database name is defined for this instance - is it created already?"
108
}
109
EXIT_NO_DATABASE_HOST = {
110
    "code": 50021,
111
    "message": "Database host is not correctly defined. Check your command arguments or the configuration files."
112
}
113
EXIT_ISOMER_URL_REQUIRED = {
114
    "code": 50100,
115
    "message": "You need to specify a source url via --url/-u for isomer",
116
}
117
EXIT_STORE_PACKAGE_NOT_FOUND = {
118
    "code": 50404,
119
    "message": "The requested package is not available in the store",
120
}
121
EXIT_WORK_IN_PROGRESS = {"code": 55555, "message": "This is work in progress"}
122
123
124
def abort(error_object, ctx=None):
125
    """Abort with a nice error message and if possible an error description
126
    url leading to the online documentation."""
127
128
    if ctx is not None:
129
        parent = ctx.parent
130
        commands = ctx.info_name
131
        while parent is not None and parent.info_name is not None:
132
            commands = parent.info_name + " " + commands
133
            parent = parent.parent
134
        log("Abort:", commands)
135
136
    url = "https://isomer.readthedocs.io/en/latest/manual/Administration/Errors/%i.html"
137
    code = -1
138
139 View Code Duplication
    if isinstance(error_object, int):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
140
        log("Unknown error code.")
141
        log(
142
            "You might be able to find more information above or here:",
143
            url % error_object,
144
        )
145
        code = error_object
146
    else:
147
        log(
148
            error_object.get(
149
                "message", "Sorry, no error message for this specific problem found."
150
            )
151
        )
152
        log(
153
            "Please see ",
154
            url % error_object.get("code", "no_code"),
155
            "for more information on this error.",
156
        )
157
        code = error_object["code"]
158
159
    if not ctx.obj.get('interactive', False):
160
        sys.exit(code)
161
162
163
def warn_error(error_object):
164
    """Warn with a nice error message and if possible an error description
165
    url leading to the online documentation."""
166
167
    url = "https://isomer.readthedocs.io/en/latest/manual/Administration/Errors/%i.html"
168 View Code Duplication
    if isinstance(error_object, int):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
169
        log("Unknown error code.")
170
        log(
171
            "You might be able to find more information above or here:",
172
            url % error_object,
173
        )
174
    else:
175
        log(
176
            error_object.get(
177
                "message", "Sorry, no error message for this specific problem found."
178
            )
179
        )
180
        log(
181
            "Please see ",
182
            url % error_object.get("code", "no_code"),
183
            "for more information.",
184
        )
185