更新NodeJS/NPM/Cucumber后,Protractor-TS-Cucumber请求回调报错排查
解决Protractor-TypeScript-Cucumber中Before钩子的statusCode未定义报错
问题描述
在Protractor-TypeScript-Cucumber框架中,使用带@Cleanup标签的Before钩子执行清理操作,代码如下:
Before({ tags: "@Cleanup" }, async function () { const JSESSION = await browser.manage().getCookie('JSESSIONID'); const value = JSESSION.value; console.log('JSESSIONID = ', value); let request = require('request'); let headers = { 'accept': '*/*', 'COOKIE': 'JSESSIONID='+value }; let options = { url: 'http://someurl.com/cleanup/12647', method: 'POST', headers: headers }; function callback(error, response, body) { if (!error && response.statusCode == 200) { console.log(body); } else { console.log('Status code is: ', response.statusCode); } } request(options, callback); })
更新NodeJS、NPM及Cucumber后出现报错:
E/launcher - TypeError: Cannot read properties of undefined (reading 'statusCode')
解决思路
- 替换废弃的
request库:request库已停止维护,与新版本NodeJS兼容性差,请求失败时可能无法正确返回response对象。建议改用axios这类活跃维护的HTTP库,重写后的代码示例:// 先安装依赖:npm install axios const axios = require('axios'); Before({ tags: "@Cleanup" }, async function () { const JSESSION = await browser.manage().getCookie('JSESSIONID'); if (!JSESSION) { console.log('未获取到有效的JSESSIONID'); return; } const value = JSESSION.value; console.log('JSESSIONID = ', value); try { const response = await axios.post('http://someurl.com/cleanup/12647', {}, { headers: { 'accept': '*/*', 'COOKIE': `JSESSIONID=${value}` } }); console.log(response.data); } catch (err) { console.log('Status code is: ', err.response?.status || '请求无响应'); console.log('错误详情:', err.message); } }) - 完善错误判断逻辑:原代码未处理
response为undefined的情况,当请求完全失败(比如网络问题)时,直接读取response.statusCode会触发报错。修改回调函数的判断逻辑:function callback(error, response, body) { if (!error && response && response.statusCode === 200) { console.log(body); } else { console.log('Status code is: ', response?.statusCode || '请求出错,无响应数据'); if (error) console.log('请求错误信息:', error); } } - 同步钩子的异步操作:原钩子使用
async声明,但内部request是回调式异步,可能导致钩子提前执行完毕,请求未完成就进入测试流程。可以将request包装为Promise,确保钩子等待请求结束:// 先安装依赖:npm install request-promise const request = require('request-promise'); Before({ tags: "@Cleanup" }, async function () { const JSESSION = await browser.manage().getCookie('JSESSIONID'); if (!JSESSION) { console.log('未获取到JSESSIONID'); return; } const value = JSESSION.value; console.log('JSESSIONID = ', value); const options = { url: 'http://someurl.com/cleanup/12647', method: 'POST', headers: { 'accept': '*/*', 'COOKIE': `JSESSIONID=${value}` }, resolveWithFullResponse: true }; try { const response = await request(options); console.log(response.body); } catch (err) { console.log('Status code is: ', err.statusCode || '请求失败'); } }) - 验证Cookie有效性:更新环境后,浏览器Cookie的获取逻辑可能有变化,先确认
JSESSION是否存在,避免携带无效Cookie发起请求导致接口无响应:const JSESSION = await browser.manage().getCookie('JSESSIONID'); if (!JSESSION) { console.log('未获取到JSESSIONID,终止清理操作'); return; } const value = JSESSION.value;
内容的提问来源于stack exchange,提问作者stackdev
相关产品推荐
相关产品推荐

