优化API返回结构与错误处理

This commit is contained in:
2025-09-07 23:21:24 +08:00
parent 4e0c898cef
commit 8dc616fa8b
4 changed files with 200 additions and 36 deletions
+90 -13
View File
@@ -44,14 +44,14 @@ class FaceRecognition:
quality_control: int = 1,
need_rotate_check: int = 1,
face_match_threshold: float = 60.0
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
"""搜索人脸"""
try:
# 验证参数
self._validate_image_params(image_url, image_path, image_file)
# 调用腾讯云API搜索人脸
results = await self.hass.async_add_executor_job(
result = await self.hass.async_add_executor_job(
self.client.search_faces,
image_url,
image_path,
@@ -66,14 +66,43 @@ class FaceRecognition:
)
# 处理结果
return self._process_search_results(results)
if result.get("success", False):
processed_faces = self._process_search_results(result.get("faces", []))
return {
"success": True,
"faces": processed_faces,
"error": None,
"error_code": None,
"error_message": None
}
else:
# 返回错误信息
return {
"success": False,
"faces": [],
"error": result.get("error"),
"error_code": result.get("error_code"),
"error_message": result.get("error_message")
}
except ValueError as ex:
_LOGGER.error("人脸搜索参数错误: %s", ex)
raise HomeAssistantError(str(ex))
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "invalid_parameter",
"error_message": str(ex)
}
except Exception as ex:
_LOGGER.error("人脸搜索失败: %s", ex)
raise HomeAssistantError(f"人脸搜索失败: {str(ex)}")
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "unknown_error",
"error_message": str(ex)
}
def _validate_image_params(self, image_url: str, image_path: str, image_file: str) -> None:
"""验证图片参数"""
@@ -152,14 +181,14 @@ class FaceRecognition:
image_file: str = None,
max_face_num: int = 1,
need_rotate_check: int = 1
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
"""获取人脸属性"""
try:
# 验证参数
self._validate_image_params(image_url, image_path, image_file)
# 调用腾讯云API获取人脸属性
results = await self.hass.async_add_executor_job(
result = await self.hass.async_add_executor_job(
self.client.get_face_attributes,
image_url,
image_path,
@@ -168,10 +197,34 @@ class FaceRecognition:
need_rotate_check
)
return results
# 处理结果
if result.get("success", False):
return {
"success": True,
"faces": result.get("faces", []),
"error": None,
"error_code": None,
"error_message": None
}
else:
# 返回错误信息
return {
"success": False,
"faces": [],
"error": result.get("error"),
"error_code": result.get("error_code"),
"error_message": result.get("error_message")
}
except Exception as ex:
self._handle_api_error("获取人脸属性", ex)
_LOGGER.error("获取人脸属性失败: %s", ex)
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "unknown_error",
"error_message": str(ex)
}
# 移除 _get_face_attributes_sync 方法,因为现在直接使用客户端的 get_face_attributes 方法
@@ -183,14 +236,14 @@ class FaceRecognition:
max_face_num: int = 1,
min_face_size: int = 34,
need_rotate_check: int = 1
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
"""检测人脸"""
try:
# 验证参数
self._validate_image_params(image_url, image_path, image_file)
# 调用腾讯云API检测人脸
results = await self.hass.async_add_executor_job(
result = await self.hass.async_add_executor_job(
self.client.detect_faces,
image_url,
image_path,
@@ -200,9 +253,33 @@ class FaceRecognition:
need_rotate_check
)
return results
# 处理结果
if result.get("success", False):
return {
"success": True,
"faces": result.get("faces", []),
"error": None,
"error_code": None,
"error_message": None
}
else:
# 返回错误信息
return {
"success": False,
"faces": [],
"error": result.get("error"),
"error_code": result.get("error_code"),
"error_message": result.get("error_message")
}
except Exception as ex:
self._handle_api_error("人脸检测", ex)
_LOGGER.error("人脸检测失败: %s", ex)
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "unknown_error",
"error_message": str(ex)
}
# 移除 _detect_faces_sync 方法,因为现在直接使用客户端的 detect_faces 方法
+33 -9
View File
@@ -134,7 +134,7 @@ async def async_face_search_service(call: ServiceCall) -> Dict[str, Any]:
need_rotate_check = data.get(ATTR_NEED_ROTATE_CHECK, 1)
face_match_threshold = data.get(ATTR_FACE_MATCH_THRESHOLD, 60.0)
results = await face_recognition.async_search_faces(
result = await face_recognition.async_search_faces(
image_url=image_url,
image_path=image_path,
image_file=image_file,
@@ -147,11 +147,19 @@ async def async_face_search_service(call: ServiceCall) -> Dict[str, Any]:
face_match_threshold=face_match_threshold
)
return {"results": results}
# 直接返回结果,包含状态和错误信息
return result
except Exception as ex:
_LOGGER.error("人脸搜索服务调用失败: %s", ex)
raise HomeAssistantError(f"人脸搜索服务调用失败: {str(ex)}")
# 返回错误信息,而不是抛出异常
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "service_error",
"error_message": str(ex)
}
async def async_detect_face_service(call: ServiceCall) -> Dict[str, Any]:
@@ -184,7 +192,7 @@ async def async_detect_face_service(call: ServiceCall) -> Dict[str, Any]:
min_face_size = data.get(ATTR_MIN_FACE_SIZE, 34)
need_rotate_check = data.get(ATTR_NEED_ROTATE_CHECK, 1)
results = await face_recognition.async_detect_faces(
result = await face_recognition.async_detect_faces(
image_url=image_url,
image_path=image_path,
image_file=image_file,
@@ -193,11 +201,19 @@ async def async_detect_face_service(call: ServiceCall) -> Dict[str, Any]:
need_rotate_check=need_rotate_check
)
return {"results": results}
# 直接返回结果,包含状态和错误信息
return result
except Exception as ex:
_LOGGER.error("人脸检测服务调用失败: %s", ex)
raise HomeAssistantError(f"人脸检测服务调用失败: {str(ex)}")
# 返回错误信息,而不是抛出异常
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "service_error",
"error_message": str(ex)
}
async def async_get_face_attributes_service(call: ServiceCall) -> Dict[str, Any]:
@@ -229,7 +245,7 @@ async def async_get_face_attributes_service(call: ServiceCall) -> Dict[str, Any]
max_face_num = data.get(ATTR_MAX_FACE_NUM, 1)
need_rotate_check = data.get(ATTR_NEED_ROTATE_CHECK, 1)
results = await face_recognition.async_get_face_attributes(
result = await face_recognition.async_get_face_attributes(
image_url=image_url,
image_path=image_path,
image_file=image_file,
@@ -237,11 +253,19 @@ async def async_get_face_attributes_service(call: ServiceCall) -> Dict[str, Any]
need_rotate_check=need_rotate_check
)
return {"results": results}
# 直接返回结果,包含状态和错误信息
return result
except Exception as ex:
_LOGGER.error("获取人脸属性服务调用失败: %s", ex)
raise HomeAssistantError(f"获取人脸属性服务调用失败: {str(ex)}")
# 返回错误信息,而不是抛出异常
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": "service_error",
"error_message": str(ex)
}
def _get_config_entry(hass: HomeAssistant):
+5 -2
View File
@@ -64,9 +64,12 @@ face_search:
name: 质量控制
description: 是否进行质量控制。
default: true
example: true
example: 1
selector:
boolean:
number:
min: 0
max: 1
mode: box
need_rotate_check:
name: 旋转检查
description: 是否进行旋转检查。
+72 -12
View File
@@ -383,7 +383,7 @@ class TencentCloudClient:
quality_control: int = 1,
need_rotate_check: int = 1,
face_match_threshold: float = 60.0
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
"""搜索人脸"""
_LOGGER.info(
"开始搜索人脸: image_url=%s, image_path=%s, image_file is not None: %s, max_face_num=%d, min_face_size=%d, max_user_num=%d, quality_control=%d, need_rotate_check=%d, face_match_threshold=%.2f",
@@ -463,7 +463,13 @@ class TencentCloudClient:
else:
_LOGGER.info("未检测到人脸")
return results
return {
"success": True,
"faces": results,
"error": None,
"error_code": None,
"error_message": None
}
except Exception as ex:
# 计算请求耗时
@@ -472,8 +478,22 @@ class TencentCloudClient:
# 记录错误日志
self._log_error("人脸搜索", request_id, ex, duration)
# 重新抛出异常
raise
# 抛出异常,而是返回包含错误信息的结构化结果
error_code = None
error_message = str(ex)
# 如果是腾讯云API异常,提取错误码和消息
if isinstance(ex, TencentCloudSDKException):
error_code = getattr(ex, "code", None)
error_message = getattr(ex, "message", str(ex))
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": error_code,
"error_message": error_message
}
# 执行带重试的API调用
return self._execute_with_retry(api_call, "人脸搜索")
@@ -486,7 +506,7 @@ class TencentCloudClient:
max_face_num: int = 1,
min_face_size: int = 34,
need_rotate_check: int = 1
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
"""检测人脸"""
_LOGGER.info(
"开始检测人脸: max_face_num=%d, min_face_size=%d, need_rotate_check=%d",
@@ -544,7 +564,13 @@ class TencentCloudClient:
else:
_LOGGER.info("未检测到人脸")
return results
return {
"success": True,
"faces": results,
"error": None,
"error_code": None,
"error_message": None
}
except Exception as ex:
# 计算请求耗时
@@ -553,8 +579,22 @@ class TencentCloudClient:
# 记录错误日志
self._log_error("人脸检测", request_id, ex, duration)
# 重新抛出异常
raise
# 抛出异常,而是返回包含错误信息的结构化结果
error_code = None
error_message = str(ex)
# 如果是腾讯云API异常,提取错误码和消息
if isinstance(ex, TencentCloudSDKException):
error_code = getattr(ex, "code", None)
error_message = getattr(ex, "message", str(ex))
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": error_code,
"error_message": error_message
}
# 执行带重试的API调用
return self._execute_with_retry(api_call, "人脸检测")
@@ -566,7 +606,7 @@ class TencentCloudClient:
image_file: str = None,
max_face_num: int = 1,
need_rotate_check: int = 1
) -> List[Dict[str, Any]]:
) -> Dict[str, Any]:
"""获取人脸属性"""
_LOGGER.info(
"开始获取人脸属性: max_face_num=%d, need_rotate_check=%d",
@@ -627,7 +667,13 @@ class TencentCloudClient:
else:
_LOGGER.info("未检测到人脸")
return results
return {
"success": True,
"faces": results,
"error": None,
"error_code": None,
"error_message": None
}
except Exception as ex:
# 计算请求耗时
@@ -636,8 +682,22 @@ class TencentCloudClient:
# 记录错误日志
self._log_error("获取人脸属性", request_id, ex, duration)
# 重新抛出异常
raise
# 抛出异常,而是返回包含错误信息的结构化结果
error_code = None
error_message = str(ex)
# 如果是腾讯云API异常,提取错误码和消息
if isinstance(ex, TencentCloudSDKException):
error_code = getattr(ex, "code", None)
error_message = getattr(ex, "message", str(ex))
return {
"success": False,
"faces": [],
"error": str(ex),
"error_code": error_code,
"error_message": error_message
}
# 执行带重试的API调用
return self._execute_with_retry(api_call, "获取人脸属性")