Flutter中含url.substring的HTTP GET请求异常失败求助
问题分析与解决方案
你遇到的现象本质并非HTTP请求失败,而是print语句抛出的异常被全局catch块捕获,导致success被错误置为false,和请求本身无关。
核心原因
你的catch块会捕获try代码块内所有异常——包括HTTP请求超时、连接失败的异常,也包括后续print(url.toString().substring(0,70))抛出的异常。如果url.toString()的长度不足70,调用substring(0,70)会触发RangeError,这个异常会进入catch块,把success设为false,让你误以为请求失败。
移除substring后,print(url.toString())不会抛错,后续逻辑正常执行,所以看起来“问题消失”。
验证步骤
在catch块中添加异常打印,就能直接确认原因:
catch (e) { print('捕获到异常:$e'); success = false; }
如果输出类似RangeError: Value not in range: 70,就完全证实了这个猜想。
解决办法
1. 安全截取字符串
先判断字符串长度再截取,避免越界:
var urlStr = url.toString(); print(urlStr.substring(0, urlStr.length < 70 ? urlStr.length : 70));
或者用Dart的Iterable方法更简洁:
print(url.toString().take(70).join());
2. 拆分catch块,精准捕获异常
把请求逻辑和后续处理逻辑拆分,只捕获请求阶段的异常,避免误捕获打印、解析的异常:
var url = Uri.parse(myRedactedUrl); try { http.Response response = await http.get(url).timeout(const Duration(seconds: 12)); // 单独处理响应和打印,内部异常不影响请求结果的判断 try { print(url.toString().substring(0,70)); if (response.statusCode == 200) { decoded = jsonDecode(response.body); success = decoded['status'] == 1; } else { success = false; } } catch (innerE) { print('响应处理/打印出错:$innerE'); // 根据业务需求决定是否修改success值 } } catch (e) { print('HTTP请求失败:$e'); success = false; }
3. 简化success赋值逻辑
可以把冗余的状态判断简化,提升代码可读性:
success = response.statusCode == 200 && decoded['status'] == 1;
内容的提问来源于stack exchange,提问作者PlayCulture
相关产品推荐
相关产品推荐

