|
1 | | -/*global SupportError */ |
2 | 1 | import { createExecutionContext } from './check'; |
3 | 2 | import RuleResult from './rule-result'; |
4 | 3 | import { |
|
8 | 7 | queue, |
9 | 8 | DqElement, |
10 | 9 | select, |
11 | | - assert |
| 10 | + assert, |
| 11 | + RuleError |
12 | 12 | } from '../utils'; |
13 | 13 | import { isVisibleToScreenReaders } from '../../commons/dom'; |
14 | 14 | import constants from '../constants'; |
@@ -181,7 +181,16 @@ Rule.prototype.runChecks = function runChecks( |
181 | 181 | const check = self._audit.checks[c.id || c]; |
182 | 182 | const option = getCheckOption(check, self.id, options); |
183 | 183 | checkQueue.defer((res, rej) => { |
184 | | - check.run(node, option, context, res, rej); |
| 184 | + check.run(node, option, context, res, error => { |
| 185 | + rej( |
| 186 | + new RuleError({ |
| 187 | + ruleId: self.id, |
| 188 | + method: `${check.id}#evaluate`, |
| 189 | + errorNode: new DqElement(node), |
| 190 | + error |
| 191 | + }) |
| 192 | + ); |
| 193 | + }); |
185 | 194 | }); |
186 | 195 | }); |
187 | 196 |
|
@@ -235,8 +244,7 @@ Rule.prototype.run = function run(context, options = {}, resolve, reject) { |
235 | 244 | // Matches throws an error when it lacks support for document methods |
236 | 245 | nodes = this.gatherAndMatchNodes(context, options); |
237 | 246 | } catch (error) { |
238 | | - // Exit the rule execution if matches fails |
239 | | - reject(new SupportError({ cause: error, ruleId: this.id })); |
| 247 | + reject(error); |
240 | 248 | return; |
241 | 249 | } |
242 | 250 |
|
@@ -312,15 +320,7 @@ Rule.prototype.runSync = function runSync(context, options = {}) { |
312 | 320 | } |
313 | 321 |
|
314 | 322 | const ruleResult = new RuleResult(this); |
315 | | - let nodes; |
316 | | - |
317 | | - try { |
318 | | - nodes = this.gatherAndMatchNodes(context, options); |
319 | | - } catch (error) { |
320 | | - // Exit the rule execution if matches fails |
321 | | - throw new SupportError({ cause: error, ruleId: this.id }); |
322 | | - } |
323 | | - |
| 323 | + const nodes = this.gatherAndMatchNodes(context, options); |
324 | 324 | if (options.performanceTimer) { |
325 | 325 | this._logGatherPerformance(nodes); |
326 | 326 | } |
@@ -451,7 +451,18 @@ Rule.prototype.gatherAndMatchNodes = function gatherAndMatchNodes( |
451 | 451 | performanceTimer.mark(markMatchesStart); |
452 | 452 | } |
453 | 453 |
|
454 | | - nodes = nodes.filter(node => this.matches(node.actualNode, node, context)); |
| 454 | + nodes = nodes.filter(node => { |
| 455 | + try { |
| 456 | + return this.matches(node.actualNode, node, context); |
| 457 | + } catch (error) { |
| 458 | + throw new RuleError({ |
| 459 | + ruleId: this.id, |
| 460 | + method: `#matches`, |
| 461 | + errorNode: new DqElement(node), |
| 462 | + error |
| 463 | + }); |
| 464 | + } |
| 465 | + }); |
455 | 466 |
|
456 | 467 | if (options.performanceTimer) { |
457 | 468 | performanceTimer.mark(markMatchesEnd); |
@@ -542,12 +553,20 @@ function sanitizeNodes(result) { |
542 | 553 | */ |
543 | 554 | Rule.prototype.after = function after(result, options) { |
544 | 555 | const afterChecks = findAfterChecks(this); |
545 | | - const ruleID = this.id; |
546 | 556 | afterChecks.forEach(check => { |
547 | 557 | const beforeResults = findCheckResults(result.nodes, check.id); |
548 | | - const checkOption = getCheckOption(check, ruleID, options); |
549 | | - |
550 | | - const afterResults = check.after(beforeResults, checkOption.options); |
| 558 | + const checkOption = getCheckOption(check, this.id, options); |
| 559 | + let afterResults; |
| 560 | + try { |
| 561 | + afterResults = check.after(beforeResults, checkOption.options); |
| 562 | + } catch (error) { |
| 563 | + throw new RuleError({ |
| 564 | + ruleId: this.id, |
| 565 | + method: `${check.id}#after`, |
| 566 | + errorNode: result.nodes?.[0]?.node, |
| 567 | + error |
| 568 | + }); |
| 569 | + } |
551 | 570 |
|
552 | 571 | if (this.reviewOnFail) { |
553 | 572 | afterResults.forEach(checkResult => { |
|
0 commit comments