// ================================================================================================ // Audio Backend - 错误处理和异常类实现 // ================================================================================================ #include "error.h" #include #include #if ALICHO_PLATFORM_WINDOWS #include #elif ALICHO_PLATFORM_UNIX #include #endif namespace audio_backend::common { // ================================================================================================ // 错误码描述映射 // ================================================================================================ static const std::unordered_map error_descriptions = { // 通用错误 {ErrorCode::SUCCESS, "操作成功"}, {ErrorCode::UNKNOWN_ERROR, "未知错误"}, {ErrorCode::INVALID_ARGUMENT, "无效参数"}, {ErrorCode::INVALID_OPERATION, "无效操作"}, {ErrorCode::NOT_IMPLEMENTED, "功能未实现"}, {ErrorCode::OUT_OF_MEMORY, "内存不足"}, {ErrorCode::OPERATION_TIMED_OUT, "操作超时"}, {ErrorCode::NOT_INITIALIZED, "未初始化"}, {ErrorCode::ALREADY_INITIALIZED, "已经初始化"}, // 文件和I/O错误 {ErrorCode::FILE_NOT_FOUND, "文件未找到"}, {ErrorCode::FILE_ACCESS_DENIED, "文件访问被拒绝"}, {ErrorCode::FILE_READ_ERROR, "文件读取错误"}, {ErrorCode::FILE_WRITE_ERROR, "文件写入错误"}, {ErrorCode::FILE_FORMAT_ERROR, "文件格式错误"}, // 音频处理错误 {ErrorCode::AUDIO_FORMAT_ERROR, "音频格式错误"}, {ErrorCode::AUDIO_DEVICE_ERROR, "音频设备错误"}, {ErrorCode::AUDIO_BUFFER_UNDERRUN, "音频缓冲区欠载"}, {ErrorCode::AUDIO_BUFFER_OVERRUN, "音频缓冲区溢出"}, {ErrorCode::AUDIO_SAMPLE_RATE_MISMATCH, "采样率不匹配"}, {ErrorCode::AUDIO_CHANNEL_COUNT_MISMATCH, "声道数不匹配"}, // 插件错误 {ErrorCode::PLUGIN_LOAD_ERROR, "插件加载错误"}, {ErrorCode::PLUGIN_NOT_FOUND, "插件未找到"}, {ErrorCode::PLUGIN_VERSION_MISMATCH, "插件版本不匹配"}, {ErrorCode::PLUGIN_INITIALIZATION_ERROR, "插件初始化错误"}, {ErrorCode::PLUGIN_COMMUNICATION_ERROR, "插件通信错误"}, {ErrorCode::PLUGIN_EXECUTION_ERROR, "插件执行错误"}, {ErrorCode::PLUGIN_TIMEOUT, "插件超时"}, // 通信错误 {ErrorCode::COMMUNICATION_ERROR, "通信错误"}, {ErrorCode::CONNECTION_ERROR, "连接错误"}, {ErrorCode::DISCONNECTED, "连接已断开"}, {ErrorCode::MESSAGE_FORMAT_ERROR, "消息格式错误"}, {ErrorCode::PROTOCOL_ERROR, "协议错误"}, {ErrorCode::TIMEOUT, "超时"}, // 系统错误 {ErrorCode::SYSTEM_ERROR, "系统错误"}, {ErrorCode::PERMISSION_DENIED, "权限被拒绝"}, {ErrorCode::NOT_ENOUGH_RESOURCES, "资源不足"} }; // ================================================================================================ // 错误分类映射 // ================================================================================================ static const std::unordered_map error_categories = { // 通用错误 {ErrorCode::SUCCESS, ErrorCategory::GENERAL}, {ErrorCode::UNKNOWN_ERROR, ErrorCategory::GENERAL}, {ErrorCode::INVALID_ARGUMENT, ErrorCategory::GENERAL}, {ErrorCode::INVALID_OPERATION, ErrorCategory::GENERAL}, {ErrorCode::NOT_IMPLEMENTED, ErrorCategory::GENERAL}, {ErrorCode::OUT_OF_MEMORY, ErrorCategory::GENERAL}, {ErrorCode::OPERATION_TIMED_OUT, ErrorCategory::GENERAL}, {ErrorCode::NOT_INITIALIZED, ErrorCategory::GENERAL}, {ErrorCode::ALREADY_INITIALIZED, ErrorCategory::GENERAL}, // 文件错误 {ErrorCode::FILE_NOT_FOUND, ErrorCategory::FILE}, {ErrorCode::FILE_ACCESS_DENIED, ErrorCategory::FILE}, {ErrorCode::FILE_READ_ERROR, ErrorCategory::FILE}, {ErrorCode::FILE_WRITE_ERROR, ErrorCategory::FILE}, {ErrorCode::FILE_FORMAT_ERROR, ErrorCategory::FILE}, // 音频错误 {ErrorCode::AUDIO_FORMAT_ERROR, ErrorCategory::AUDIO}, {ErrorCode::AUDIO_DEVICE_ERROR, ErrorCategory::AUDIO}, {ErrorCode::AUDIO_BUFFER_UNDERRUN, ErrorCategory::AUDIO}, {ErrorCode::AUDIO_BUFFER_OVERRUN, ErrorCategory::AUDIO}, {ErrorCode::AUDIO_SAMPLE_RATE_MISMATCH, ErrorCategory::AUDIO}, {ErrorCode::AUDIO_CHANNEL_COUNT_MISMATCH, ErrorCategory::AUDIO}, // 插件错误 {ErrorCode::PLUGIN_LOAD_ERROR, ErrorCategory::PLUGIN}, {ErrorCode::PLUGIN_NOT_FOUND, ErrorCategory::PLUGIN}, {ErrorCode::PLUGIN_VERSION_MISMATCH, ErrorCategory::PLUGIN}, {ErrorCode::PLUGIN_INITIALIZATION_ERROR, ErrorCategory::PLUGIN}, {ErrorCode::PLUGIN_COMMUNICATION_ERROR, ErrorCategory::PLUGIN}, {ErrorCode::PLUGIN_EXECUTION_ERROR, ErrorCategory::PLUGIN}, {ErrorCode::PLUGIN_TIMEOUT, ErrorCategory::PLUGIN}, // 通信错误 {ErrorCode::COMMUNICATION_ERROR, ErrorCategory::COMMUNICATION}, {ErrorCode::CONNECTION_ERROR, ErrorCategory::COMMUNICATION}, {ErrorCode::DISCONNECTED, ErrorCategory::COMMUNICATION}, {ErrorCode::MESSAGE_FORMAT_ERROR, ErrorCategory::COMMUNICATION}, {ErrorCode::PROTOCOL_ERROR, ErrorCategory::COMMUNICATION}, {ErrorCode::TIMEOUT, ErrorCategory::COMMUNICATION}, // 系统错误 {ErrorCode::SYSTEM_ERROR, ErrorCategory::SYSTEM}, {ErrorCode::PERMISSION_DENIED, ErrorCategory::SYSTEM}, {ErrorCode::NOT_ENOUGH_RESOURCES, ErrorCategory::SYSTEM} }; // ================================================================================================ // 公共函数实现 // ================================================================================================ ErrorCategory get_error_category(ErrorCode code) { auto it = error_categories.find(code); if (it != error_categories.end()) { return it->second; } return ErrorCategory::GENERAL; } std::string get_error_description(ErrorCode code) { auto it = error_descriptions.find(code); if (it != error_descriptions.end()) { return it->second; } return "未知错误代码: " + std::to_string(static_cast(code)); } std::exception_ptr create_exception(ErrorCode code, const std::string& message, const std::string& details) { ErrorCategory category = get_error_category(code); try { switch (category) { case ErrorCategory::FILE: throw FileException(code, message, details); case ErrorCategory::AUDIO: throw AudioException(code, message, details); case ErrorCategory::PLUGIN: throw PluginException(code, message, details); case ErrorCategory::COMMUNICATION: throw CommunicationException(code, message, details); case ErrorCategory::SYSTEM: throw SystemException(code, message, details); default: throw AudioBackendException(code, message, details); } } catch (...) { return std::current_exception(); } } void throw_exception(ErrorCode code, const std::string& message, const std::string& details) { std::rethrow_exception(create_exception(code, message, details)); } void check_error(bool condition, ErrorCode error_code, const std::string& message, const std::string& details) { if (condition) { throw_exception(error_code, message, details); } } ErrorCode system_error_to_error_code(int system_error) { #if ALICHO_PLATFORM_WINDOWS switch (system_error) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: return ErrorCode::FILE_NOT_FOUND; case ERROR_ACCESS_DENIED: return ErrorCode::FILE_ACCESS_DENIED; case ERROR_NOT_ENOUGH_MEMORY: case ERROR_OUTOFMEMORY: return ErrorCode::OUT_OF_MEMORY; case ERROR_TIMEOUT: return ErrorCode::OPERATION_TIMED_OUT; case ERROR_INVALID_PARAMETER: return ErrorCode::INVALID_ARGUMENT; default: return ErrorCode::SYSTEM_ERROR; } #elif ALICHO_PLATFORM_UNIX switch (system_error) { case ENOENT: return ErrorCode::FILE_NOT_FOUND; case EACCES: case EPERM: return ErrorCode::FILE_ACCESS_DENIED; case ENOMEM: return ErrorCode::OUT_OF_MEMORY; case ETIMEDOUT: return ErrorCode::OPERATION_TIMED_OUT; case EINVAL: return ErrorCode::INVALID_ARGUMENT; default: return ErrorCode::SYSTEM_ERROR; } #else return ErrorCode::SYSTEM_ERROR; #endif } ErrorCode std_error_to_error_code(const std::error_code& ec) { if (ec.category() == std::generic_category()) { return system_error_to_error_code(ec.value()); } else if (ec.category() == AudioBackendErrorCategory::instance()) { return static_cast(ec.value()); } else { return ErrorCode::SYSTEM_ERROR; } } // ================================================================================================ // ErrorHandler实现 // ================================================================================================ void ErrorHandler::add_error_handler(const ErrorCallback& handler) { handlers_.push_back(handler); } void ErrorHandler::remove_error_handler(const ErrorCallback& handler) { // 注意:这个比较可能不会按预期工作,因为std::function的比较很复杂 // 在实际使用中,可能需要使用其他方式来管理处理器(比如返回ID) auto it = std::find_if(handlers_.begin(), handlers_.end(), [&handler](const ErrorCallback& h) { // 这里的比较不太可靠,应该考虑使用其他方式 return &h == &handler; }); if (it != handlers_.end()) { handlers_.erase(it); } } void ErrorHandler::handle_error(const AudioBackendException& exception) { for (const auto& handler : handlers_) { try { handler(exception); } catch (...) { // 忽略错误处理器中的异常,防止无限递归 } } } void ErrorHandler::handle_error(ErrorCode code, const std::string& message, const std::string& details) { try { AudioBackendException exception(code, message, details); handle_error(exception); } catch (...) { // 忽略创建异常时的错误 } } void ErrorHandler::handle_exception(std::exception_ptr eptr) { if (!eptr) return; try { std::rethrow_exception(eptr); } catch (const AudioBackendException& e) { handle_error(e); } catch (const std::exception& e) { // 对于其他标准异常,创建一个通用的AudioBackendException AudioBackendException wrapper(ErrorCode::UNKNOWN_ERROR, e.what()); handle_error(wrapper); } catch (...) { // 对于其他异常,创建一个未知错误 AudioBackendException wrapper(ErrorCode::UNKNOWN_ERROR, "未知异常类型"); handle_error(wrapper); } } void ErrorHandler::clear_handlers() { handlers_.clear(); } } // namespace audio_backend::common