fishertools 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fishertools/__init__.py +82 -0
- fishertools/config/__init__.py +24 -0
- fishertools/config/manager.py +247 -0
- fishertools/config/models.py +96 -0
- fishertools/config/parser.py +265 -0
- fishertools/decorators.py +93 -0
- fishertools/documentation/__init__.py +38 -0
- fishertools/documentation/api.py +242 -0
- fishertools/documentation/generator.py +502 -0
- fishertools/documentation/models.py +126 -0
- fishertools/documentation/visual.py +583 -0
- fishertools/errors/__init__.py +29 -0
- fishertools/errors/exceptions.py +191 -0
- fishertools/errors/explainer.py +303 -0
- fishertools/errors/formatters.py +386 -0
- fishertools/errors/models.py +228 -0
- fishertools/errors/patterns.py +119 -0
- fishertools/errors/recovery.py +467 -0
- fishertools/examples/__init__.py +22 -0
- fishertools/examples/models.py +118 -0
- fishertools/examples/repository.py +770 -0
- fishertools/helpers.py +116 -0
- fishertools/integration.py +451 -0
- fishertools/learn/__init__.py +18 -0
- fishertools/learn/examples.py +550 -0
- fishertools/learn/tips.py +281 -0
- fishertools/learning/__init__.py +32 -0
- fishertools/learning/core.py +349 -0
- fishertools/learning/models.py +112 -0
- fishertools/learning/progress.py +314 -0
- fishertools/learning/session.py +500 -0
- fishertools/learning/tutorial.py +626 -0
- fishertools/legacy/__init__.py +76 -0
- fishertools/legacy/deprecated.py +261 -0
- fishertools/legacy/deprecation.py +149 -0
- fishertools/safe/__init__.py +16 -0
- fishertools/safe/collections.py +242 -0
- fishertools/safe/files.py +240 -0
- fishertools/safe/strings.py +15 -0
- fishertools/utils.py +57 -0
- fishertools-0.2.1.dist-info/METADATA +256 -0
- fishertools-0.2.1.dist-info/RECORD +81 -0
- fishertools-0.2.1.dist-info/WHEEL +5 -0
- fishertools-0.2.1.dist-info/licenses/LICENSE +21 -0
- fishertools-0.2.1.dist-info/top_level.txt +2 -0
- tests/__init__.py +6 -0
- tests/conftest.py +25 -0
- tests/test_config/__init__.py +3 -0
- tests/test_config/test_basic_config.py +57 -0
- tests/test_config/test_config_error_handling.py +287 -0
- tests/test_config/test_config_properties.py +435 -0
- tests/test_documentation/__init__.py +3 -0
- tests/test_documentation/test_documentation_properties.py +253 -0
- tests/test_documentation/test_visual_documentation_properties.py +444 -0
- tests/test_errors/__init__.py +3 -0
- tests/test_errors/test_api.py +301 -0
- tests/test_errors/test_error_handling.py +354 -0
- tests/test_errors/test_explainer.py +173 -0
- tests/test_errors/test_formatters.py +338 -0
- tests/test_errors/test_models.py +248 -0
- tests/test_errors/test_patterns.py +270 -0
- tests/test_examples/__init__.py +3 -0
- tests/test_examples/test_example_repository_properties.py +204 -0
- tests/test_examples/test_specific_examples.py +303 -0
- tests/test_integration.py +298 -0
- tests/test_integration_enhancements.py +462 -0
- tests/test_learn/__init__.py +3 -0
- tests/test_learn/test_examples.py +221 -0
- tests/test_learn/test_tips.py +285 -0
- tests/test_learning/__init__.py +3 -0
- tests/test_learning/test_interactive_learning_properties.py +337 -0
- tests/test_learning/test_learning_system_properties.py +194 -0
- tests/test_learning/test_progress_tracking_properties.py +279 -0
- tests/test_legacy/__init__.py +3 -0
- tests/test_legacy/test_backward_compatibility.py +236 -0
- tests/test_legacy/test_deprecation_warnings.py +208 -0
- tests/test_safe/__init__.py +3 -0
- tests/test_safe/test_collections_properties.py +189 -0
- tests/test_safe/test_files.py +104 -0
- tests/test_structure.py +58 -0
- tests/test_structure_enhancements.py +115 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom exception classes for fishertools error handling.
|
|
3
|
+
|
|
4
|
+
This module defines the exception hierarchy for fishertools, providing
|
|
5
|
+
specific error types for different failure scenarios.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FishertoolsError(Exception):
|
|
10
|
+
"""
|
|
11
|
+
Base exception class for all fishertools-specific errors.
|
|
12
|
+
|
|
13
|
+
This is the parent class for all custom exceptions in fishertools.
|
|
14
|
+
It provides a consistent interface and allows catching all fishertools
|
|
15
|
+
errors with a single except clause.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, message: str, original_error: Exception = None):
|
|
19
|
+
"""
|
|
20
|
+
Initialize the fishertools error.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
message: Human-readable error message in Russian
|
|
24
|
+
original_error: The original exception that caused this error (optional)
|
|
25
|
+
"""
|
|
26
|
+
super().__init__(message)
|
|
27
|
+
self.message = message
|
|
28
|
+
self.original_error = original_error
|
|
29
|
+
|
|
30
|
+
def __str__(self) -> str:
|
|
31
|
+
"""Return the error message."""
|
|
32
|
+
return self.message
|
|
33
|
+
|
|
34
|
+
def get_full_message(self) -> str:
|
|
35
|
+
"""
|
|
36
|
+
Get the full error message including original error if available.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Complete error message with context
|
|
40
|
+
"""
|
|
41
|
+
if self.original_error:
|
|
42
|
+
return f"{self.message} (Причина: {self.original_error})"
|
|
43
|
+
return self.message
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ExplanationError(FishertoolsError):
|
|
47
|
+
"""
|
|
48
|
+
Exception raised when error explanation fails.
|
|
49
|
+
|
|
50
|
+
This exception is raised when the ErrorExplainer cannot create
|
|
51
|
+
a proper explanation for a given exception, typically due to
|
|
52
|
+
pattern matching failures or internal processing errors.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, message: str, exception_type: str = None, original_error: Exception = None):
|
|
56
|
+
"""
|
|
57
|
+
Initialize the explanation error.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
message: Description of what went wrong during explanation
|
|
61
|
+
exception_type: The type of exception that couldn't be explained
|
|
62
|
+
original_error: The original exception that caused this error
|
|
63
|
+
"""
|
|
64
|
+
super().__init__(message, original_error)
|
|
65
|
+
self.exception_type = exception_type
|
|
66
|
+
|
|
67
|
+
def get_full_message(self) -> str:
|
|
68
|
+
"""Get the full error message with exception type context."""
|
|
69
|
+
base_message = super().get_full_message()
|
|
70
|
+
if self.exception_type:
|
|
71
|
+
return f"{base_message} (Тип исключения: {self.exception_type})"
|
|
72
|
+
return base_message
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class FormattingError(FishertoolsError):
|
|
76
|
+
"""
|
|
77
|
+
Exception raised when output formatting fails.
|
|
78
|
+
|
|
79
|
+
This exception is raised when formatters cannot properly format
|
|
80
|
+
an ErrorExplanation, typically due to invalid formatter configuration
|
|
81
|
+
or output generation issues.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, message: str, formatter_type: str = None, original_error: Exception = None):
|
|
85
|
+
"""
|
|
86
|
+
Initialize the formatting error.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
message: Description of what went wrong during formatting
|
|
90
|
+
formatter_type: The type of formatter that failed
|
|
91
|
+
original_error: The original exception that caused this error
|
|
92
|
+
"""
|
|
93
|
+
super().__init__(message, original_error)
|
|
94
|
+
self.formatter_type = formatter_type
|
|
95
|
+
|
|
96
|
+
def get_full_message(self) -> str:
|
|
97
|
+
"""Get the full error message with formatter type context."""
|
|
98
|
+
base_message = super().get_full_message()
|
|
99
|
+
if self.formatter_type:
|
|
100
|
+
return f"{base_message} (Тип форматтера: {self.formatter_type})"
|
|
101
|
+
return base_message
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class ConfigurationError(FishertoolsError):
|
|
105
|
+
"""
|
|
106
|
+
Exception raised when configuration is invalid.
|
|
107
|
+
|
|
108
|
+
This exception is raised when ExplainerConfig or other configuration
|
|
109
|
+
objects contain invalid values that prevent proper system operation.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(self, message: str, config_field: str = None, config_value: str = None, original_error: Exception = None):
|
|
113
|
+
"""
|
|
114
|
+
Initialize the configuration error.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
message: Description of the configuration problem
|
|
118
|
+
config_field: The configuration field that has an invalid value
|
|
119
|
+
config_value: The invalid value that caused the error
|
|
120
|
+
original_error: The original exception that caused this error
|
|
121
|
+
"""
|
|
122
|
+
super().__init__(message, original_error)
|
|
123
|
+
self.config_field = config_field
|
|
124
|
+
self.config_value = config_value
|
|
125
|
+
|
|
126
|
+
def get_full_message(self) -> str:
|
|
127
|
+
"""Get the full error message with configuration context."""
|
|
128
|
+
base_message = super().get_full_message()
|
|
129
|
+
if self.config_field and self.config_value:
|
|
130
|
+
return f"{base_message} (Поле: {self.config_field}, Значение: {self.config_value})"
|
|
131
|
+
elif self.config_field:
|
|
132
|
+
return f"{base_message} (Поле: {self.config_field})"
|
|
133
|
+
return base_message
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class PatternError(FishertoolsError):
|
|
137
|
+
"""
|
|
138
|
+
Exception raised when error pattern operations fail.
|
|
139
|
+
|
|
140
|
+
This exception is raised when ErrorPattern objects cannot be created,
|
|
141
|
+
loaded, or used properly, typically due to invalid pattern definitions
|
|
142
|
+
or pattern matching failures.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __init__(self, message: str, pattern_type: str = None, original_error: Exception = None):
|
|
146
|
+
"""
|
|
147
|
+
Initialize the pattern error.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
message: Description of the pattern problem
|
|
151
|
+
pattern_type: The type of pattern that caused the error
|
|
152
|
+
original_error: The original exception that caused this error
|
|
153
|
+
"""
|
|
154
|
+
super().__init__(message, original_error)
|
|
155
|
+
self.pattern_type = pattern_type
|
|
156
|
+
|
|
157
|
+
def get_full_message(self) -> str:
|
|
158
|
+
"""Get the full error message with pattern type context."""
|
|
159
|
+
base_message = super().get_full_message()
|
|
160
|
+
if self.pattern_type:
|
|
161
|
+
return f"{base_message} (Тип паттерна: {self.pattern_type})"
|
|
162
|
+
return base_message
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class SafeUtilityError(FishertoolsError):
|
|
166
|
+
"""
|
|
167
|
+
Exception raised when safe utility operations fail.
|
|
168
|
+
|
|
169
|
+
This exception is raised when safe utility functions encounter
|
|
170
|
+
errors that cannot be handled gracefully, typically due to
|
|
171
|
+
invalid inputs or system-level failures.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
def __init__(self, message: str, utility_name: str = None, original_error: Exception = None):
|
|
175
|
+
"""
|
|
176
|
+
Initialize the safe utility error.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
message: Description of the utility problem
|
|
180
|
+
utility_name: The name of the utility function that failed
|
|
181
|
+
original_error: The original exception that caused this error
|
|
182
|
+
"""
|
|
183
|
+
super().__init__(message, original_error)
|
|
184
|
+
self.utility_name = utility_name
|
|
185
|
+
|
|
186
|
+
def get_full_message(self) -> str:
|
|
187
|
+
"""Get the full error message with utility name context."""
|
|
188
|
+
base_message = super().get_full_message()
|
|
189
|
+
if self.utility_name:
|
|
190
|
+
return f"{base_message} (Утилита: {self.utility_name})"
|
|
191
|
+
return base_message
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main error explainer implementation.
|
|
3
|
+
|
|
4
|
+
This module contains the ErrorExplainer class and explain_error function.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional, List
|
|
8
|
+
from .models import ErrorExplanation, ExplainerConfig, ErrorPattern
|
|
9
|
+
from .patterns import load_default_patterns
|
|
10
|
+
from .exceptions import ExplanationError, FormattingError, ConfigurationError, FishertoolsError
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ErrorExplainer:
|
|
14
|
+
"""
|
|
15
|
+
Main class for explaining Python errors in simple terms.
|
|
16
|
+
|
|
17
|
+
Uses pattern matching to provide contextual explanations for different
|
|
18
|
+
types of Python exceptions.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: Optional[ExplainerConfig] = None):
|
|
22
|
+
"""
|
|
23
|
+
Initialize the error explainer with optional configuration.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
config: Configuration for the explainer behavior
|
|
27
|
+
|
|
28
|
+
Raises:
|
|
29
|
+
ConfigurationError: If the provided configuration is invalid
|
|
30
|
+
ExplanationError: If pattern loading fails
|
|
31
|
+
"""
|
|
32
|
+
try:
|
|
33
|
+
self.config = config or ExplainerConfig()
|
|
34
|
+
self.patterns = self._load_patterns()
|
|
35
|
+
except Exception as e:
|
|
36
|
+
if isinstance(e, (ConfigurationError, ExplanationError)):
|
|
37
|
+
raise
|
|
38
|
+
raise ExplanationError(f"Не удалось инициализировать ErrorExplainer: {e}", original_error=e)
|
|
39
|
+
|
|
40
|
+
def _load_patterns(self) -> List[ErrorPattern]:
|
|
41
|
+
"""
|
|
42
|
+
Load error patterns for matching exceptions.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
List of ErrorPattern objects
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
ExplanationError: If patterns cannot be loaded
|
|
49
|
+
"""
|
|
50
|
+
try:
|
|
51
|
+
return load_default_patterns()
|
|
52
|
+
except Exception as e:
|
|
53
|
+
raise ExplanationError(f"Не удалось загрузить паттерны ошибок: {e}", original_error=e)
|
|
54
|
+
|
|
55
|
+
def explain(self, exception: Exception) -> ErrorExplanation:
|
|
56
|
+
"""
|
|
57
|
+
Create an explanation for the given exception.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
exception: The exception to explain
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Structured explanation of the error
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
ExplanationError: If explanation creation fails
|
|
67
|
+
"""
|
|
68
|
+
if not isinstance(exception, Exception):
|
|
69
|
+
raise ExplanationError(f"Параметр должен быть экземпляром Exception, получен {type(exception).__name__}")
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
# Try to find a matching pattern
|
|
73
|
+
pattern = self._match_pattern(exception)
|
|
74
|
+
|
|
75
|
+
if pattern:
|
|
76
|
+
return self._create_explanation_from_pattern(exception, pattern)
|
|
77
|
+
else:
|
|
78
|
+
return self._create_fallback_explanation(exception)
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
if isinstance(e, ExplanationError):
|
|
82
|
+
raise
|
|
83
|
+
# Graceful degradation - create a minimal explanation if all else fails
|
|
84
|
+
return self._create_emergency_explanation(exception, e)
|
|
85
|
+
|
|
86
|
+
def _match_pattern(self, exception: Exception) -> Optional[ErrorPattern]:
|
|
87
|
+
"""
|
|
88
|
+
Find the best matching pattern for the given exception.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
exception: The exception to match
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Matching ErrorPattern or None if no match found
|
|
95
|
+
"""
|
|
96
|
+
try:
|
|
97
|
+
for pattern in self.patterns:
|
|
98
|
+
if pattern.matches(exception):
|
|
99
|
+
return pattern
|
|
100
|
+
return None
|
|
101
|
+
except Exception as e:
|
|
102
|
+
# If pattern matching fails, log the error but don't raise
|
|
103
|
+
# This allows fallback explanation to work
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
def _create_explanation_from_pattern(self, exception: Exception,
|
|
107
|
+
pattern: ErrorPattern) -> ErrorExplanation:
|
|
108
|
+
"""
|
|
109
|
+
Create explanation using a matched pattern.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
exception: The original exception
|
|
113
|
+
pattern: The matched pattern
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
ErrorExplanation based on the pattern
|
|
117
|
+
|
|
118
|
+
Raises:
|
|
119
|
+
ExplanationError: If explanation creation fails
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
return ErrorExplanation(
|
|
123
|
+
original_error=str(exception),
|
|
124
|
+
error_type=type(exception).__name__,
|
|
125
|
+
simple_explanation=pattern.explanation,
|
|
126
|
+
fix_tip=pattern.tip,
|
|
127
|
+
code_example=pattern.example,
|
|
128
|
+
additional_info=f"Частые причины: {', '.join(pattern.common_causes)}"
|
|
129
|
+
)
|
|
130
|
+
except Exception as e:
|
|
131
|
+
raise ExplanationError(f"Не удалось создать объяснение из паттерна: {e}",
|
|
132
|
+
exception_type=type(exception).__name__, original_error=e)
|
|
133
|
+
|
|
134
|
+
def _create_fallback_explanation(self, exception: Exception) -> ErrorExplanation:
|
|
135
|
+
"""
|
|
136
|
+
Create a generic explanation for unsupported exceptions.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
exception: The exception to explain
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Generic ErrorExplanation
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
error_type = type(exception).__name__
|
|
146
|
+
|
|
147
|
+
return ErrorExplanation(
|
|
148
|
+
original_error=str(exception),
|
|
149
|
+
error_type=error_type,
|
|
150
|
+
simple_explanation=f"Произошла ошибка типа {error_type}. Это означает, что в вашем коде что-то пошло не так.",
|
|
151
|
+
fix_tip="Внимательно прочитайте сообщение об ошибке и проверьте строку кода, где произошла ошибка. Убедитесь, что все переменные определены и имеют правильные типы.",
|
|
152
|
+
code_example=f"# Пример обработки ошибки {error_type}:\ntry:\n # ваш код здесь\n pass\nexcept {error_type} as e:\n print(f'Ошибка: {{e}}')",
|
|
153
|
+
additional_info="Если вы не можете решить проблему самостоятельно, попробуйте поискать информацию об этом типе ошибки в документации Python или задать вопрос на форуме."
|
|
154
|
+
)
|
|
155
|
+
except Exception as e:
|
|
156
|
+
# If even fallback fails, create emergency explanation
|
|
157
|
+
return self._create_emergency_explanation(exception, e)
|
|
158
|
+
|
|
159
|
+
def _create_emergency_explanation(self, exception: Exception, original_error: Exception) -> ErrorExplanation:
|
|
160
|
+
"""
|
|
161
|
+
Create a minimal explanation when all other methods fail.
|
|
162
|
+
|
|
163
|
+
This is the last resort for graceful degradation.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
exception: The original exception to explain
|
|
167
|
+
original_error: The error that prevented normal explanation
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
Minimal ErrorExplanation that should always work
|
|
171
|
+
"""
|
|
172
|
+
try:
|
|
173
|
+
error_type = getattr(type(exception), '__name__', 'Unknown')
|
|
174
|
+
error_message = str(exception) if exception else 'Неизвестная ошибка'
|
|
175
|
+
|
|
176
|
+
return ErrorExplanation(
|
|
177
|
+
original_error=error_message,
|
|
178
|
+
error_type=error_type,
|
|
179
|
+
simple_explanation="Произошла ошибка в вашем коде. К сожалению, не удалось создать подробное объяснение.",
|
|
180
|
+
fix_tip="Проверьте сообщение об ошибке выше и попробуйте найти проблему в коде. Обратитесь за помощью, если не можете решить проблему самостоятельно.",
|
|
181
|
+
code_example="# Общий способ обработки ошибок:\ntry:\n # ваш код\n pass\nexcept Exception as e:\n print(f'Ошибка: {e}')",
|
|
182
|
+
additional_info=f"Внутренняя ошибка fishertools: {original_error}"
|
|
183
|
+
)
|
|
184
|
+
except Exception:
|
|
185
|
+
# Absolute last resort - create explanation with minimal dependencies
|
|
186
|
+
return ErrorExplanation(
|
|
187
|
+
original_error="Критическая ошибка",
|
|
188
|
+
error_type="Critical",
|
|
189
|
+
simple_explanation="Произошла критическая ошибка в системе объяснения ошибок.",
|
|
190
|
+
fix_tip="Обратитесь к разработчикам fishertools с описанием проблемы.",
|
|
191
|
+
code_example="# Обратитесь за помощью",
|
|
192
|
+
additional_info="Критическая ошибка системы"
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def explain_error(exception: Exception,
|
|
197
|
+
language: str = 'ru',
|
|
198
|
+
format_type: str = 'console',
|
|
199
|
+
**kwargs) -> None:
|
|
200
|
+
"""
|
|
201
|
+
Main public API function for explaining Python errors in simple terms.
|
|
202
|
+
|
|
203
|
+
This function takes any Python exception and provides a beginner-friendly
|
|
204
|
+
explanation in Russian, including what the error means, how to fix it,
|
|
205
|
+
and a relevant code example.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
exception: The Python exception to explain (required)
|
|
209
|
+
language: Language for explanations ('ru' or 'en', default: 'ru')
|
|
210
|
+
format_type: Output format ('console', 'plain', 'json', default: 'console')
|
|
211
|
+
**kwargs: Additional formatting parameters:
|
|
212
|
+
- use_colors: Whether to use colors in console output (default: True)
|
|
213
|
+
- show_original_error: Whether to show original error message (default: True)
|
|
214
|
+
- show_traceback: Whether to show traceback (default: False)
|
|
215
|
+
|
|
216
|
+
Raises:
|
|
217
|
+
TypeError: If exception parameter is not an Exception instance
|
|
218
|
+
ValueError: If language or format_type parameters are invalid
|
|
219
|
+
|
|
220
|
+
Examples:
|
|
221
|
+
>>> try:
|
|
222
|
+
... result = 10 / 0
|
|
223
|
+
... except Exception as e:
|
|
224
|
+
... explain_error(e)
|
|
225
|
+
|
|
226
|
+
>>> explain_error(TypeError("'str' object cannot be interpreted as an integer"))
|
|
227
|
+
|
|
228
|
+
>>> explain_error(ValueError("invalid literal"), format_type='json')
|
|
229
|
+
"""
|
|
230
|
+
# Parameter validation with custom exceptions
|
|
231
|
+
if not isinstance(exception, Exception):
|
|
232
|
+
raise TypeError(f"Параметр 'exception' должен быть экземпляром Exception, "
|
|
233
|
+
f"получен {type(exception).__name__}")
|
|
234
|
+
|
|
235
|
+
# Validate language parameter
|
|
236
|
+
valid_languages = ['ru', 'en']
|
|
237
|
+
if language not in valid_languages:
|
|
238
|
+
raise ValueError(f"Параметр 'language' должен быть одним из {valid_languages}, "
|
|
239
|
+
f"получен '{language}'")
|
|
240
|
+
|
|
241
|
+
# Validate format_type parameter
|
|
242
|
+
valid_formats = ['console', 'plain', 'json']
|
|
243
|
+
if format_type not in valid_formats:
|
|
244
|
+
raise ValueError(f"Параметр 'format_type' должен быть одним из {valid_formats}, "
|
|
245
|
+
f"получен '{format_type}'")
|
|
246
|
+
|
|
247
|
+
try:
|
|
248
|
+
from .formatters import get_formatter
|
|
249
|
+
|
|
250
|
+
# Create configuration based on parameters
|
|
251
|
+
config = ExplainerConfig(
|
|
252
|
+
language=language,
|
|
253
|
+
format_type=format_type,
|
|
254
|
+
use_colors=kwargs.get('use_colors', True),
|
|
255
|
+
show_original_error=kwargs.get('show_original_error', True),
|
|
256
|
+
show_traceback=kwargs.get('show_traceback', False)
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Create explainer and get explanation
|
|
260
|
+
explainer = ErrorExplainer(config)
|
|
261
|
+
explanation = explainer.explain(exception)
|
|
262
|
+
|
|
263
|
+
# Get appropriate formatter and format output
|
|
264
|
+
formatter = get_formatter(format_type, use_colors=config.use_colors)
|
|
265
|
+
formatted_output = formatter.format(explanation)
|
|
266
|
+
|
|
267
|
+
# Output to console by default
|
|
268
|
+
print(formatted_output)
|
|
269
|
+
|
|
270
|
+
except ExplanationError as e:
|
|
271
|
+
# Handle explanation-specific errors gracefully
|
|
272
|
+
print(f"Ошибка при объяснении исключения: {e.get_full_message()}")
|
|
273
|
+
print(f"Оригинальная ошибка: {type(exception).__name__}: {exception}")
|
|
274
|
+
if e.original_error:
|
|
275
|
+
print(f"Техническая информация: {e.original_error}")
|
|
276
|
+
|
|
277
|
+
except FormattingError as e:
|
|
278
|
+
# Handle formatting errors - try to show basic explanation
|
|
279
|
+
print(f"Ошибка форматирования: {e.get_full_message()}")
|
|
280
|
+
try:
|
|
281
|
+
# Try to create a basic explanation without formatting
|
|
282
|
+
explainer = ErrorExplainer()
|
|
283
|
+
explanation = explainer.explain(exception)
|
|
284
|
+
print(f"Простое объяснение: {explanation.simple_explanation}")
|
|
285
|
+
print(f"Совет: {explanation.fix_tip}")
|
|
286
|
+
except Exception:
|
|
287
|
+
print(f"Оригинальная ошибка: {type(exception).__name__}: {exception}")
|
|
288
|
+
|
|
289
|
+
except ConfigurationError as e:
|
|
290
|
+
# Handle configuration errors
|
|
291
|
+
print(f"Ошибка конфигурации: {e.get_full_message()}")
|
|
292
|
+
print(f"Оригинальная ошибка: {type(exception).__name__}: {exception}")
|
|
293
|
+
|
|
294
|
+
except FishertoolsError as e:
|
|
295
|
+
# Handle any other fishertools-specific errors
|
|
296
|
+
print(f"Ошибка fishertools: {e.get_full_message()}")
|
|
297
|
+
print(f"Оригинальная ошибка: {type(exception).__name__}: {exception}")
|
|
298
|
+
|
|
299
|
+
except Exception as e:
|
|
300
|
+
# Ultimate fallback for any unexpected errors
|
|
301
|
+
print(f"Неожиданная ошибка в fishertools: {e}")
|
|
302
|
+
print(f"Оригинальная ошибка: {type(exception).__name__}: {exception}")
|
|
303
|
+
print("Пожалуйста, сообщите об этой проблеме разработчикам fishertools.")
|