This commit is contained in:
dengqichen 2025-11-19 15:36:57 +08:00
parent ae1720c866
commit 6d70376a26
2 changed files with 53 additions and 9 deletions

View File

@ -1,4 +1,5 @@
const BaseAction = require('../core/base-action');
const { ConfigurationError, ValidationError } = require('../core/errors');
/**
* 验证动作 - 检测页面状态并根据结果采取行动
@ -31,7 +32,11 @@ class VerifyAction extends BaseAction {
} = this.config;
if (!conditions) {
throw new Error('Verify action 需要 conditions 参数');
throw new ConfigurationError(
'Verify action 需要 conditions 参数',
'conditions',
{ action: 'verify', config: this.config }
);
}
this.log('debug', '开始验证...');
@ -225,7 +230,12 @@ class VerifyAction extends BaseAction {
case 'throw':
// 抛出异常,触发重试或错误处理
throw new Error(`验证${resultType}: ${reason}`);
throw new ValidationError(
`验证${resultType}`,
resultType === '成功' ? '满足成功条件' : '满足失败条件',
resultType,
{ reason, action: 'verify' }
);
case 'return':
// 返回结果,由调用者处理

View File

@ -1,5 +1,6 @@
const BaseAction = require('../core/base-action');
const SmartSelector = require('../core/smart-selector');
const { ConfigurationError, ElementNotFoundError, TimeoutError } = require('../core/errors');
/**
* 等待动作
@ -25,7 +26,11 @@ class WaitAction extends BaseAction {
return await this.waitForUrl();
default:
throw new Error(`未知的等待类型: ${type}`);
throw new ConfigurationError(
`未知的等待类型: ${type}`,
'type',
{ supportedTypes: ['delay', 'element', 'navigation', 'condition', 'url'] }
);
}
}
@ -47,7 +52,11 @@ class WaitAction extends BaseAction {
const timeout = this.config.timeout || 10000;
if (!selector) {
throw new Error('缺少选择器配置');
throw new ConfigurationError(
'缺少选择器配置',
'find',
{ action: 'wait', type: 'element' }
);
}
this.log('debug', '等待元素出现');
@ -56,7 +65,11 @@ class WaitAction extends BaseAction {
const element = await smartSelector.find(timeout);
if (!element) {
throw new Error(`元素未出现(超时 ${timeout}ms`);
throw new ElementNotFoundError(selector, {
action: 'wait',
type: 'element',
timeout
});
}
this.log('debug', '✓ 元素已出现');
@ -88,7 +101,11 @@ class WaitAction extends BaseAction {
const timeout = this.config.timeout || 10000;
if (!handler) {
throw new Error('缺少条件处理函数');
throw new ConfigurationError(
'缺少条件处理函数',
'handler',
{ action: 'wait', type: 'condition' }
);
}
this.log('debug', '等待自定义条件');
@ -108,7 +125,11 @@ class WaitAction extends BaseAction {
await new Promise(resolve => setTimeout(resolve, 500));
}
throw new Error('条件未满足(超时)');
throw new TimeoutError(
`waitForCondition: ${handler}`,
timeout,
{ handler, elapsed: Date.now() - startTime }
);
}
/**
@ -121,7 +142,11 @@ class WaitAction extends BaseAction {
const urlEquals = this.config.urlEquals;
if (!urlContains && !urlNotContains && !urlEquals) {
throw new Error('需要指定 urlContains、urlNotContains 或 urlEquals');
throw new ConfigurationError(
'需要指定 urlContains、urlNotContains 或 urlEquals',
'urlContains/urlNotContains/urlEquals',
{ action: 'wait', type: 'url' }
);
}
this.log('debug', '等待 URL 变化');
@ -161,7 +186,16 @@ class WaitAction extends BaseAction {
}
const finalUrl = this.page.url();
throw new Error(`URL 条件未满足(超时),当前 URL: ${finalUrl}`);
throw new TimeoutError(
'waitForUrl',
timeout,
{
urlContains,
urlNotContains,
urlEquals,
actualUrl: finalUrl
}
);
}
}