树莓派对接BMP280上传数据遇解析错误,try-except应优先捕获哪类异常
网络异常处理方案
核心问题解答
- 无需逐层捕获socket、urllib3抛出的底层错误,优先捕获上层封装的网络连接异常即可:如果直接用requests库请求,捕获
requests.exceptions.ConnectionError;如果用Adafruit官方IO客户端,额外捕获AdafruitIO_ConnectionError,所有DNS解析失败、连接建立失败的问题都会被这两类异常覆盖,不会出现漏抓的情况。 - 不要使用裸
except捕获所有异常,避免把BMP280硬件读取错误、代码逻辑错误这类不可自动恢复的问题也吞掉,影响后续故障排查效率。
实现逻辑
捕获到网络异常后按以下流程处理即可:
- 将错误信息和对应的时间戳写入本地日志文件,方便后续回溯故障发生的具体时段
- 调用
sleep等待30分钟,无需额外编写WiFi重连逻辑,系统会自动处理网络恢复,重试时请求会自动使用可用的网络连接 - 等待结束后回到主逻辑重新尝试采集上传
参考代码示例
import time import logging import requests # 若使用Adafruit官方IO客户端,导入对应异常类 from Adafruit_IO import Client, AdafruitIO_ConnectionError # 配置本地日志,错误信息永久存储在同目录sensor_log.log中 logging.basicConfig( filename='sensor_log.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s' ) # Adafruit IO配置 ADAFRUIT_IO_USER = "你的用户名" ADAFRUIT_IO_KEY = "你的密钥" aio = Client(ADAFRUIT_IO_USER, ADAFRUIT_IO_KEY) # 你原本的采集间隔(单位:秒) COLLECT_INTERVAL = 60 # 异常重试等待间隔(30分钟) RETRY_INTERVAL = 1800 while True: try: # 原有逻辑:读取BMP280传感器数据 temp = bmp280.get_temperature() pressure = bmp280.get_pressure() # 上传到Adafruit IO aio.send("temperature-feed", temp) aio.send("pressure-feed", pressure) # 按预设间隔等待下一次采集 time.sleep(COLLECT_INTERVAL) except (requests.exceptions.ConnectionError, AdafruitIO_ConnectionError) as e: # 记录网络错误 logging.error(f"网络连接失败:{str(e)},{RETRY_INTERVAL//60}分钟后重试") time.sleep(RETRY_INTERVAL) except Exception as e: # 其他未知错误单独记录,缩短重试间隔避免长时间断采 logging.error(f"未知运行错误:{str(e)},10分钟后重试") time.sleep(600)
额外优化建议
- 给DNS配置加锁避免被DHCP刷新覆盖:编辑
/etc/dhcp/dhclient.conf,新增prepend domain-name-servers 8.8.8.8, 8.8.4.4;配置,重启后DNS配置不会丢失 - 配置systemd服务将脚本设为开机自启,树莓派意外断电重启后会自动启动采集程序,无需手动操作
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

