当前位置: 首页 > article >正文

别再让程序‘死’得不明不白:用C++的system_error库给你的错误信息‘加个Buff’

别再让程序‘死’得不明不白用C的system_error库给你的错误信息‘加个Buff’凌晨三点服务器监控突然报警。你揉着惺忪的睡眼打开日志只见一行冰冷的Error: 13躺在屏幕上——这就像医生告诉你你生病了却不说是感冒还是骨折。在C的世界里system_error库就是那个能把Error 13翻译成Permission denied的贴心翻译官而今天我们要让它成为你调试工具箱里的瑞士军刀。1. 为什么你的错误处理像在玩猜谜游戏记得上次遇到File not found时花了多少时间排查吗传统错误处理有三大原罪数字哑谜errno、HRESULT这些数字代码就像密码本不查文档根本看不懂信息碎片化错误描述分散在日志、返回值和异常消息里拼图游戏都没这么难上下文丢失一个简单的Invalid argument可能来自文件权限、网络连接或内存分配// 典型的猜猜我是谁式错误处理 int fd open(config.json, O_RDONLY); if (fd -1) { std::cerr Error: errno std::endl; // 输出Error 2 }system_error的解决方案是把错误变成自描述对象std::error_code ec; std::filesystem::path p(config.json); if (!std::filesystem::exists(p, ec)) { std::cerr Error: ec.message(); // 输出No such file or directory }2. 解剖system_error的三层结构体系这个库的精妙之处在于它的分类学思维就像生物学的界门纲目科属种2.1 error_code错误的DNA样本每个error_code包含两个核心基因value()原始错误码如Linux的errno值category()错误所属的生态圈std::error_code ec std::make_error_code(std::errc::permission_denied); std::cout Value: ec.value() \n // 输出13 Category: ec.category().name() // 输出generic Message: ec.message(); // 输出Permission denied2.2 error_category错误的家族树标准库预定义了这些主要家族类别涵盖范围典型错误示例generic_categoryPOSIX标准错误EPERM, ENOENT, EINTRsystem_category操作系统特定错误Windows的HRESULTiostream_category流操作错误文件打开失败future_category异步操作错误承诺值已设置2.3 error_condition错误的通用诊断书这是跨平台的错误语义层比如std::error_code ec std::make_error_code(std::errc::no_such_file_or_directory); if (ec std::errc::no_such_file_or_directory) { // 无论底层是Linux的ENOENT还是Windows的ERROR_FILE_NOT_FOUND std::cerr 文件失踪了; }3. 打造你的定制化错误系统当标准分类不够用时可以创建自己的错误王国3.1 继承error_categoryclass http_error_category : public std::error_category { public: const char* name() const noexcept override { return http; } std::string message(int ev) const override { switch (ev) { case 400: return Bad Request; case 404: return Not Found; case 500: return Internal Server Error; default: return Unknown Error; } } }; const std::error_category http_category() { static http_error_category instance; return instance; }3.2 定义枚举和转换规则enum class http_errc { bad_request 400, not_found 404, server_error 500 }; std::error_code make_error_code(http_errc e) { return {static_castint(e), http_category()}; } namespace std { template struct is_error_code_enumhttp_errc : true_type {}; }现在可以像使用系统错误一样使用自定义错误std::error_code ec http_errc::not_found; if (ec http_errc::not_found) { std::cout 优雅地处理404: ec.message(); }4. 实战给HTTP客户端穿上错误防护甲让我们把这些技术融入一个真实的HTTP客户端class http_client { public: std::string fetch(const std::string url) { std::error_code ec; CURL* curl curl_easy_init(); if (!curl) { ec http_errc::server_error; throw std::system_error(ec, CURL初始化失败); } std::string response; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); CURLcode res curl_easy_perform(curl); if (res ! CURLE_OK) { ec translate_curl_error(res); curl_easy_cleanup(curl); throw std::system_error(ec, HTTP请求失败); } long http_code 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, http_code); curl_easy_cleanup(curl); if (http_code 400) { ec static_casthttp_errc(http_code); throw std::system_error(ec, HTTP错误响应); } return response; } private: std::error_code translate_curl_error(CURLcode code) { // 将libcurl错误映射到我们的错误系统 switch (code) { case CURLE_COULDNT_CONNECT: return std::make_error_code(std::errc::connection_refused); case CURLE_OPERATION_TIMEDOUT: return std::make_error_code(std::errc::timed_out); default: return http_errc::server_error; } } };使用时错误处理变得语义明确try { http_client client; auto data client.fetch(https://example.com/api); } catch (const std::system_error e) { std::cerr [ e.code().category().name() ] e.what() : e.code().message(); if (e.code() http_errc::not_found) { // 特殊处理404 } else if (e.code() std::errc::timed_out) { // 处理超时 } }5. 错误处理的进阶技巧5.1 错误码的哈希与比较std::error_code ec1 std::errc::permission_denied; std::error_code ec2 std::make_error_code(std::errc::permission_denied); std::hashstd::error_code hasher; std::cout 哈希值: hasher(ec1) \n 相等性: (ec1 ec2); // 输出15.2 与日志系统集成void log_error(const std::system_error e) { nlohmann::json error_info { {timestamp, std::time(nullptr)}, {category, e.code().category().name()}, {code, e.code().value()}, {message, e.what()}, {description, e.code().message()}, {stacktrace, boost::stacktrace::to_string( boost::stacktrace::stacktrace())} }; std::ofstream log(error.log, std::ios::app); log error_info.dump(4) \n; }5.3 错误码的国际化class localized_category : public std::error_category { public: std::string message(int ev) const override { // 根据当前locale返回翻译后的消息 return translate_error(ev, std::locale().name()); } };在大型项目中我们通常会建立错误处理中间层class error_handler { public: using handler_fn std::functionvoid(const std::error_code); void register_handler(std::error_condition cond, handler_fn fn) { handlers_[cond] fn; } void handle(const std::error_code ec) { auto it handlers_.find(ec.default_error_condition()); if (it ! handlers_.end()) { it-second(ec); } else { default_handler_(ec); } } private: std::mapstd::error_condition, handler_fn handlers_; handler_fn default_handler_ [](const auto ec) { throw std::system_error(ec); }; };使用示例error_handler handler; // 注册特定错误处理 handler.register_handler(std::errc::timed_out, [](const auto ec) { std::cerr 超时重试中...\n; std::this_thread::sleep_for(1s); retry_operation(); }); // 注册默认处理 handler.register_handler(std::errc::permission_denied, [](const auto ec) { send_alert_email(权限错误, ec.message()); throw; }); // 使用 try { some_operation(); } catch (const std::system_error e) { handler.handle(e.code()); }

相关文章:

别再让程序‘死’得不明不白:用C++的system_error库给你的错误信息‘加个Buff’

别再让程序‘死’得不明不白:用C的system_error库给你的错误信息‘加个Buff’ 凌晨三点,服务器监控突然报警。你揉着惺忪的睡眼打开日志,只见一行冰冷的"Error: 13"躺在屏幕上——这就像医生告诉你"你生病了"&#xff0c…...

从t-SNE到UMAP:我的单细胞转录组数据分析工具升级之路(含参数避坑指南)

从t-SNE到UMAP:单细胞转录组数据分析的降维革命 第一次用t-SNE可视化10X Genomics单细胞数据时,我被那些五彩斑斓的细胞簇惊艳到了——直到发现同一个细胞群在重复运行时出现在完全不同的坐标位置。更糟的是,当我试图比较两个样本时&#xff…...

告别眼疲劳!我的IDEA 2023.3终极美化方案:字体、主题、彩虹括号与背景图全攻略

程序员护眼指南:IDEA 2023.3深度定制方案 作为一名每天与代码相伴8小时以上的开发者,我深刻理解眼睛干涩、颈椎酸痛带来的困扰。经过两年反复调试和眼科医生建议,这套配置方案让我的工作效率提升40%,视力疲劳显著缓解。今天分享的…...

BilibiliDown:如何实现一键批量下载B站视频和音频的完整指南

BilibiliDown:如何实现一键批量下载B站视频和音频的完整指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mir…...

对比自行搭建与使用 Taotoken 聚合服务在延迟体感上的差异

使用 Taotoken 聚合服务对模型调用体验的影响 1. 自行接入多模型 API 的常见挑战 在 Taotoken 这类聚合平台出现之前,开发者需要自行对接不同厂商的大模型 API。这一过程往往伴随着几个显著的体验问题。首先是连接稳定性,由于不同厂商的服务器部署位置…...

League Akari 终极指南:如何快速提升英雄联盟游戏效率的完整教程

League Akari 终极指南:如何快速提升英雄联盟游戏效率的完整教程 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari 是一…...

Simulink仿真避坑指南:信号发生器选不对,你的自动控制模型可能白做了

Simulink信号发生器实战指南:如何为控制模型精准匹配激励信号 在控制系统仿真领域,一个经常被低估却至关重要的问题是:你的激励信号真的能揭示系统特性吗? 许多工程师花费数周调整PID参数,却因为信号源选择不当导致仿真…...

LLM2LLM:基于迭代式数据增强的大语言模型高效微调实战

1. 项目概述:用大模型自己“卷”自己,实现数据增强的迭代循环最近在折腾大语言模型(LLM)的微调时,一个绕不开的难题就是高质量数据。标注成本高、数据量不足、数据多样性不够,这些问题常常让模型性能卡在瓶…...

让B站直播弹幕变身YouTube风格:BLiveChat新手完全指南

让B站直播弹幕变身YouTube风格:BLiveChat新手完全指南 【免费下载链接】blivechat 用于OBS的仿YouTube风格的bilibili直播评论栏 项目地址: https://gitcode.com/gh_mirrors/bl/blivechat 还在为B站直播弹幕单调的样式而烦恼吗?想让你的直播间拥有…...

告别服务器噪音:3步掌握戴尔服务器风扇智能控制技巧

告别服务器噪音:3步掌握戴尔服务器风扇智能控制技巧 【免费下载链接】dell_fans_controller A tool for control the Dell server fans speed, it sends the control instruction by ipmitool over LAN for Windows, it is a GUI application which is built by C# …...

AI 辅助 ArkTS 开发实战:用 Cursor + WorkBuddy 让鸿蒙开发效率翻倍

AI 辅助 ArkTS 开发实战:用 Cursor WorkBuddy 让鸿蒙开发效率翻倍 鸿蒙 HarmonyOS NEXT 已全面转向 ArkTS,但很多开发者还在用"复制 CSDN 代码→改报错→再复制"的方式开发。本文结合真实项目,分享如何用 AI 工具链把鸿蒙开发效率…...

3分钟掌握Axure中文界面:免费语言包轻松搞定英文烦恼

3分钟掌握Axure中文界面:免费语言包轻松搞定英文烦恼 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP…...

中小企业AI营销破局:为什么你需要一台超算一体机?

在AI重构商业逻辑的今天,中小企业正面临前所未有的营销困境。卡特加特超算一体机的出现,正在改写这一局面。流量红利见顶、获客成本攀升、内容生产乏力——这是当下绝大多数中小企业主的真实写照。当大企业用AI工具构建营销矩阵时,中小企业却…...

OpenClaw监控台v3.5.0:从工程面板到产品化运维驾驶舱的蜕变

1. 项目概述:从“工程面板”到“产品化监控台”的蜕变如果你和我一样,在本地运行着像 OpenClaw 这样的复杂工作流引擎,那你一定也经历过这样的场景:打开官方 Dashboard,面对满屏的原始 JSON、晦涩的字段名和密密麻麻的…...

ChatGPT-Next-Web部署与定制指南:从零构建私有AI应用

1. 项目概述与核心价值最近在折腾AI应用部署的朋友,估计没少听过magicCJ/ChatGPT-Next-Web这个项目。简单来说,它是一个基于Next.js框架构建的、功能强大且界面优雅的ChatGPT Web应用。但如果你只把它理解成一个“网页版聊天机器人”,那就大大…...

视觉语言模型在GUI自动化测试中的应用与优化

1. 项目背景与核心价值去年在开发一个自动化测试工具时,我遇到了一个棘手问题:如何让机器真正"看懂"软件界面?传统基于元素树的识别方式在应对动态布局时频繁失效,这促使我开始探索视觉语言模型(VLM&#xf…...

终极免费NCM音乐解锁工具:5分钟完全掌握ncmppGui

终极免费NCM音乐解锁工具:5分钟完全掌握ncmppGui 【免费下载链接】ncmppGui 一个使用C编写的极速ncm转换GUI工具 项目地址: https://gitcode.com/gh_mirrors/nc/ncmppGui 你是否曾为音乐平台下载的歌曲只能在特定应用中播放而烦恼?NCM格式就像一道…...

手把手调试:用逻辑分析仪抓SPI波形,根治FATFS在Flash上的FR_DISK_ERR故障

深度解析SPI-FLASH挂载FATFS的硬件层故障排查实战 当嵌入式系统中SPI Flash挂载FATFS文件系统频繁返回FR_DISK_ERR错误时,多数开发者会陷入软件调试的泥潭。本文将揭示如何通过逻辑分析仪捕获SPI波形,从硬件通信层面精准定位问题根源。不同于传统的"…...

从电视盒子到全能服务器:Armbian在Amlogic设备上的技术突破与实践

从电视盒子到全能服务器:Armbian在Amlogic设备上的技术突破与实践 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s905, s905…...

GraphRAG 到底在干嘛?——微软这篇博客的深度拆解

原文:GraphRAG: Unlocking LLM discovery on narrative private data - Microsoft Research 微软 2024 年初发了一篇技术博客,核心就一句话:传统 RAG 在复杂数据面前不够用,GraphRAG 用知识图谱 图聚类补上了这块短板。 这不是学…...

动物森友会岛屿设计的终极解决方案:Happy Island Designer完整指南

动物森友会岛屿设计的终极解决方案:Happy Island Designer完整指南 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)",是一个在线工具,它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会》(Anim…...

终极指南:MicMute - 一键快速控制麦克风静音的高效工具

终极指南:MicMute - 一键快速控制麦克风静音的高效工具 【免费下载链接】MicMute Mute default mic clicking tray icon or shortcut 项目地址: https://gitcode.com/gh_mirrors/mi/MicMute 在远程办公和在线会议成为日常的今天,高效控制麦克风状…...

PHP电商订单分布式处理的7个致命陷阱:90%团队踩坑的幂等性、事务一致性与消息重复消费真相

更多请点击: https://intelliparadigm.com 第一章:PHP电商订单分布式处理的典型架构全景 现代高并发电商系统中,单体 PHP 应用已无法承载秒杀、大促等场景下的订单洪峰。分布式订单处理架构通过解耦核心环节,实现横向扩展与故障隔…...

Taotoken 用量看板如何帮助团队精细化管理 API 成本

Taotoken 用量看板如何帮助团队精细化管理 API 成本 1. 用量看板的核心功能 Taotoken 用量看板为团队管理者提供了多维度的 API 调用数据可视化能力。通过控制台的数据分析模块,可以实时查看当前和历史 token 消耗情况。系统默认按自然日聚合数据,支持…...

AI代码安全审查实战:从原理到CI/CD集成的完整指南

1. 项目概述:当AI成为你的代码审查员最近在开源社区和内部研发团队里,一个叫“ai-code-security”的项目开始频繁被提及。简单来说,它就是一个利用人工智能模型,自动扫描和分析代码库,以识别潜在安全漏洞和不良编码实践…...

【.NET 9 AI开发终极指南】:微软官方未公开的5大AI集成黑科技首次深度披露

更多请点击: https://intelliparadigm.com 第一章:.NET 9 AI开发全景概览与环境奠基 .NET 9 将原生 AI 支持深度融入平台核心,首次提供 Microsoft.Extensions.AI 统一抽象层,屏蔽底层模型提供商(如 OpenAI、Azure AI…...

3步打造AI短视频自动化生产线:MoneyPrinterPlus终极方案

3步打造AI短视频自动化生产线:MoneyPrinterPlus终极方案 【免费下载链接】MoneyPrinterPlus AI一键批量生成各类短视频,自动批量混剪短视频,自动把视频发布到抖音,快手,小红书,视频号上,赚钱从来没有这么容易过! 支持本地语音模型chatTTS,fasterwhisper,GPTSoVITS,支…...

如何每天节省20分钟?终极淘宝淘金币自动化脚本完全指南

如何每天节省20分钟?终极淘宝淘金币自动化脚本完全指南 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本,包含蚂蚁森林收取能量,芭芭农场全任务,解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojinbi 你是…...

语音情绪识别中的标签主观性问题与解决方案

1. 项目背景与核心挑战 语音情绪识别技术近年来在客服质检、心理健康评估、智能交互等领域展现出巨大应用潜力。但当我们真正将算法模型部署到实际业务场景时,发现一个长期被忽视的根本性问题:人类对语音情绪的主观判断存在显著差异。同一段语音样本&…...

Flowable审批人设置踩坑记:如何精准匹配‘部门+角色’组合(附完整代码)

Flowable动态审批人配置实战:从部门角色组合到精准待办查询 审批流程中的候选人配置一直是工作流实施中最容易踩坑的环节之一。特别是在需要结合部门架构和角色权限的复杂场景下,简单的固定值设置往往会导致待办任务无法正确显示或审批权限混乱。本文将分…...