VWED_server/config/error_code_mapping.py
2025-07-14 10:29:37 +08:00

631 lines
20 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
错误代码映射配置
用于为不同类型的错误分配固定的告警代码
"""
from typing import Dict, List, Tuple
import re
class ErrorCodeMapping:
"""错误代码映射管理器"""
# 基础告警代码范围定义
BASE_RANGES = {
'system': (5400, 5499), # 系统相关错误 5400-5499
'task': (5500, 5699), # 任务相关错误 5500-5699
'robot': (5700, 5799), # 机器人相关错误 5700-5799
'database': (5800, 5849), # 数据库相关错误 5800-5849
'network': (5850, 5899), # 网络相关错误 5850-5899
'auth': (5900, 5949), # 认证相关错误 5900-5949
'validation': (5950, 5999), # 验证相关错误 5950-5999
}
# 错误类型和关键词映射
ERROR_TYPE_PATTERNS = {
# 任务相关错误
'task_execution_failed': {
'patterns': [
r'任务执行失败',
r'task execution failed',
r'execute.*failed',
r'执行.*失败',
],
'code': 5500,
'category': 'task'
},
'task_execution_timeout': {
'patterns': [
r'任务执行超时',
r'task execution timeout',
r'execute.*timeout',
r'执行.*超时',
],
'code': 5501,
'category': 'task'
},
'task_scheduling_failed': {
'patterns': [
r'任务调度失败',
r'task scheduling failed',
r'调度.*失败',
r'scheduling.*failed',
],
'code': 5502,
'category': 'task'
},
'task_not_found': {
'patterns': [
r'任务.*不存在',
r'task.*not found',
r'找不到.*任务',
r'任务.*未找到',
],
'code': 5503,
'category': 'task'
},
'task_params_invalid': {
'patterns': [
r'任务参数.*无效',
r'task parameters invalid',
r'参数.*错误',
r'invalid.*parameters',
],
'code': 5504,
'category': 'task'
},
'task_status_error': {
'patterns': [
r'任务状态.*错误',
r'task status error',
r'状态.*异常',
r'status.*error',
],
'code': 5505,
'category': 'task'
},
'task_block_execution_failed': {
'patterns': [
r'块.*执行.*失败',
r'block.*execution.*failed',
r'任务块.*失败',
r'block.*failed',
],
'code': 5506,
'category': 'task'
},
'task_template_error': {
'patterns': [
r'任务模板.*错误',
r'task template error',
r'模板.*异常',
r'template.*error',
],
'code': 5507,
'category': 'task'
},
'task_sync_failed': {
'patterns': [
r'同步任务.*失败',
r'sync.*task.*failed',
r'同步任务到.*系统.*失败',
r'任务同步.*失败',
],
'code': 5508,
'category': 'task'
},
'task_start_failed': {
'patterns': [
r'启动任务失败',
r'start.*task.*failed',
r'任务启动.*失败',
r'task.*startup.*failed',
],
'code': 5509,
'category': 'task'
},
'task_run_failed': {
'patterns': [
r'运行任务失败',
r'run.*task.*failed',
r'任务运行.*失败',
r'task.*execution.*failed',
],
'code': 5510,
'category': 'task'
},
'task_scene_id_not_exist': {
'patterns': [
r'此场景id不存在',
r'场景.*不存在',
r'scene.*id.*not.*exist',
r'scene.*not.*found',
],
'code': 5511,
'category': 'task'
},
'task_child_block_failed': {
'patterns': [
r'子块.*执行失败',
r'child.*block.*failed',
r'子块.*失败',
r'child.*execution.*failed',
],
'code': 5512,
'category': 'task'
},
# 机器人相关错误
'robot_connection_failed': {
'patterns': [
r'机器人.*连接.*失败',
r'robot.*connection.*failed',
r'AGV.*连接.*失败',
r'vehicle.*connection.*failed',
],
'code': 5700,
'category': 'robot'
},
'robot_battery_low': {
'patterns': [
r'机器人.*电池.*低',
r'robot.*battery.*low',
r'AGV.*电量.*低',
r'电池.*不足',
],
'code': 5701,
'category': 'robot'
},
'robot_navigation_failed': {
'patterns': [
r'机器人.*导航.*失败',
r'robot.*navigation.*failed',
r'AGV.*导航.*失败',
r'导航.*异常',
],
'code': 5702,
'category': 'robot'
},
'robot_task_failed': {
'patterns': [
r'机器人.*任务.*失败',
r'robot.*task.*failed',
r'AGV.*任务.*失败',
r'机器人.*执行.*失败',
],
'code': 5703,
'category': 'robot'
},
'robot_select_amr_failed': {
'patterns': [
r'为任务选择AMR失败',
r'选择.*AMR.*失败',
r'select.*amr.*failed',
r'amr.*selection.*failed',
],
'code': 5704,
'category': 'robot'
},
'robot_select_execution_failed': {
'patterns': [
r'选择执行机器人失败',
r'选择.*机器人.*失败',
r'robot.*selection.*failed',
r'select.*execution.*robot.*failed',
],
'code': 5705,
'category': 'robot'
},
'robot_tianfeng_task_id_not_exist': {
'patterns': [
r'此天风任务id不存在',
r'天风任务.*不存在',
r'tianfeng.*task.*id.*not.*exist',
r'tianfeng.*task.*not.*found',
],
'code': 5706,
'category': 'robot'
},
'robot_block_action_detail_failed': {
'patterns': [
r'调用获取任务块动作详情接口失败',
r'获取任务块动作.*详情.*失败',
r'task.*block.*action.*detail.*failed',
r'get.*task.*block.*action.*failed',
],
'code': 5707,
'category': 'robot'
},
'robot_block_detail_failed': {
'patterns': [
r'调用获取任务块详情接口失败',
r'获取任务块.*详情.*失败',
r'task.*block.*detail.*failed',
r'get.*task.*block.*failed',
],
'code': 5708,
'category': 'robot'
},
# 数据库相关错误
'database_connection_failed': {
'patterns': [
r'数据库.*连接.*失败',
r'database.*connection.*failed',
r'DB.*连接.*失败',
r'连接.*数据库.*失败',
],
'code': 5800,
'category': 'database'
},
'database_query_failed': {
'patterns': [
r'数据库.*查询.*失败',
r'database.*query.*failed',
r'SQL.*执行.*失败',
r'查询.*失败',
],
'code': 5801,
'category': 'database'
},
'database_transaction_failed': {
'patterns': [
r'数据库.*事务.*失败',
r'database.*transaction.*failed',
r'事务.*回滚',
r'transaction.*rollback',
],
'code': 5802,
'category': 'database'
},
# 网络相关错误
'network_connection_failed': {
'patterns': [
r'网络.*连接.*失败',
r'network.*connection.*failed',
r'连接.*超时',
r'connection.*timeout',
],
'code': 5850,
'category': 'network'
},
'network_request_failed': {
'patterns': [
r'网络.*请求.*失败',
r'network.*request.*failed',
r'HTTP.*请求.*失败',
r'request.*failed',
],
'code': 5851,
'category': 'network'
},
'network_timeout': {
'patterns': [
r'网络.*超时',
r'network.*timeout',
r'请求.*超时',
r'request.*timeout',
r'TimeoutError',
r'CancelledError',
],
'code': 5852,
'category': 'network'
},
'network_connect_refused': {
'patterns': [
r'ConnectionRefusedError',
r'Connect call failed',
r'Cannot connect to host',
r'连接.*被拒绝',
r'connection.*refused',
],
'code': 5853,
'category': 'network'
},
'network_api_call_failed': {
'patterns': [
r'调用.*接口失败',
r'调用.*API.*失败',
r'api.*call.*failed',
r'interface.*call.*failed',
r'调用系统任务创建任务接口失败',
],
'code': 5854,
'category': 'network'
},
# 系统相关错误
'system_resource_exhausted': {
'patterns': [
r'系统.*资源.*耗尽',
r'system.*resource.*exhausted',
r'内存.*不足',
r'memory.*insufficient',
],
'code': 5400,
'category': 'system'
},
'system_configuration_error': {
'patterns': [
r'系统.*配置.*错误',
r'system.*configuration.*error',
r'配置.*异常',
r'configuration.*error',
],
'code': 5401,
'category': 'system'
},
'system_service_unavailable': {
'patterns': [
r'系统.*服务.*不可用',
r'system.*service.*unavailable',
r'服务.*不可用',
r'service.*unavailable',
],
'code': 5402,
'category': 'system'
},
# 认证相关错误
'auth_token_invalid': {
'patterns': [
r'认证.*令牌.*无效',
r'auth.*token.*invalid',
r'token.*过期',
r'token.*expired',
],
'code': 5900,
'category': 'auth'
},
'auth_permission_denied': {
'patterns': [
r'权限.*拒绝',
r'permission.*denied',
r'访问.*被拒绝',
r'access.*denied',
],
'code': 5901,
'category': 'auth'
},
# 验证相关错误
'validation_parameter_invalid': {
'patterns': [
r'参数.*验证.*失败',
r'parameter.*validation.*failed',
r'参数.*无效',
r'invalid.*parameter',
],
'code': 5950,
'category': 'validation'
},
'validation_data_format_error': {
'patterns': [
r'数据.*格式.*错误',
r'data.*format.*error',
r'格式.*不正确',
r'format.*invalid',
],
'code': 5951,
'category': 'validation'
},
# 程序错误相关
'program_attribute_error': {
'patterns': [
r'AttributeError',
r'\'.*\' object has no attribute \'.*\'',
r'属性.*错误',
r'attribute.*error',
r'\'NoneType\' object has no attribute \'get\'',
],
'code': 5952,
'category': 'validation'
},
'program_type_error': {
'patterns': [
r'TypeError',
r'类型.*错误',
r'type.*error',
r'NoneType.*object',
],
'code': 5953,
'category': 'validation'
},
'program_runtime_error': {
'patterns': [
r'RuntimeError',
r'运行时.*错误',
r'runtime.*error',
r'执行时.*错误',
],
'code': 5954,
'category': 'validation'
},
}
# 模块特定的错误代码偏移
MODULE_OFFSETS = {
'services.task_service': 0,
'services.task_execution': 5,
'services.task_scheduler': 10,
'services.enhanced_scheduler.task_scheduler': 15,
'services.task_edit_service': 20,
'services.sync_service': 25,
'services.robot_scheduler': 30,
'services.calldevice_service': 35,
'services.modbus_config_service': 40,
'services.script_service': 45,
'services.execution.block_executor': 50,
'services.execution.task_executor': 55,
'routes.task_api': 60,
'routes.task_edit_api': 65,
'routes.calldevice_api': 70,
'routes.modbus_config_api': 75,
'app.task_edit_api': 80,
'middlewares.error_handlers': 85,
'middleware.request_logger': 90,
'utils.alert_sync': 95,
'data.models': 100,
'data.session': 105,
'core.intelligence': 110,
}
@classmethod
def get_error_code(cls, logger_name: str, message: str) -> int:
"""
根据logger名称和消息内容获取错误代码
Args:
logger_name: logger名称
message: 错误消息
Returns:
错误代码
"""
# 首先尝试匹配错误类型
error_type = cls._match_error_type(message)
if error_type:
# 获取基础代码
base_code = cls.ERROR_TYPE_PATTERNS[error_type]['code']
# 根据模块添加偏移量
module_offset = cls._get_module_offset(logger_name)
# 确保代码在合理范围内
final_code = base_code + module_offset
# 确保不超过最大值
if final_code > 9999:
final_code = base_code
return final_code
# 如果没有匹配的错误类型,使用通用代码生成
return cls._generate_fallback_code(logger_name, message)
@classmethod
def _match_error_type(cls, message: str) -> str:
"""
匹配错误类型
Args:
message: 错误消息
Returns:
错误类型名称如果没有匹配则返回None
"""
message_lower = message.lower()
for error_type, config in cls.ERROR_TYPE_PATTERNS.items():
for pattern in config['patterns']:
if re.search(pattern, message_lower, re.IGNORECASE):
return error_type
return None
@classmethod
def _get_module_offset(cls, logger_name: str) -> int:
"""
获取模块的偏移量
Args:
logger_name: logger名称
Returns:
偏移量
"""
# 尝试精确匹配
if logger_name in cls.MODULE_OFFSETS:
return cls.MODULE_OFFSETS[logger_name]
# 尝试部分匹配
for module, offset in cls.MODULE_OFFSETS.items():
if logger_name.startswith(module):
return offset
return 0
@classmethod
def _generate_fallback_code(cls, logger_name: str, message: str) -> int:
"""
生成备用错误代码(用于无法匹配的错误)
Args:
logger_name: logger名称
message: 错误消息
Returns:
错误代码
"""
import hashlib
# 使用简化的消息内容生成代码
simplified_message = cls._simplify_message(message)
hash_input = f"{logger_name}:{simplified_message}"
hash_value = hashlib.md5(hash_input.encode()).hexdigest()
# 生成在6000-6999范围内的代码未分类错误
code = int(hash_value[:4], 16) % 1000 + 6000
return code
@classmethod
def _simplify_message(cls, message: str) -> str:
"""
简化错误消息,去除变量部分
Args:
message: 原始错误消息
Returns:
简化后的消息
"""
# 移除常见的变量部分
simplified = re.sub(r'\d+', '[NUMBER]', message) # 替换数字
simplified = re.sub(r'[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}', '[UUID]', simplified) # 替换UUID
simplified = re.sub(r'/[^/\s]+', '[PATH]', simplified) # 替换路径
simplified = re.sub(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', '[IP]', simplified) # 替换IP地址
simplified = re.sub(r'\s+', ' ', simplified).strip() # 清理空白字符
return simplified
@classmethod
def get_error_info(cls, error_code: int) -> Dict:
"""
根据错误代码获取错误信息
Args:
error_code: 错误代码
Returns:
错误信息字典
"""
# 查找匹配的错误类型
for error_type, config in cls.ERROR_TYPE_PATTERNS.items():
if config['code'] <= error_code < config['code'] + 200: # 允许偏移量
return {
'error_type': error_type,
'category': config['category'],
'base_code': config['code'],
'description': f"{config['category']}相关错误: {error_type}"
}
# 根据代码范围确定类别
for category, (start, end) in cls.BASE_RANGES.items():
if start <= error_code <= end:
return {
'error_type': 'unknown',
'category': category,
'base_code': start,
'description': f"{category}相关错误"
}
return {
'error_type': 'unknown',
'category': 'unknown',
'base_code': error_code,
'description': '未知错误'
}