Skip to content

Commit

Permalink
Better errors from visitable (#640)
Browse files Browse the repository at this point in the history
* Better errors from visitable

This adds the actual error message from Ember's router to the (too generic) message from `visitable`. This is especially important when your test needs to know what kind of error was triggered. For example some tests might want to handle `TransitionAborted` errors differently, see emberjs/ember-test-helpers#332 (comment).

* Pass original error message from visit as Error#cause

* preserve original error instance

...under the `cause.error`

* doc: add a brief note about the `cause.error`

in the `visitable` error instance

---------

Co-authored-by: Ruslan Hrabovyi <kudgo.test@gmail.com>
  • Loading branch information
simonihmig and ro0gr authored Mar 13, 2024
1 parent a290565 commit ed51bb1
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 4 deletions.
1 change: 1 addition & 0 deletions addon/src/-private/better-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function throwBetterError(node, key, error, { selector } = {}) {
const wrapperError = new PageObjectError(message, {
cause: {
message,
error: error.cause,
key,
node,
selector,
Expand Down
10 changes: 7 additions & 3 deletions addon/src/properties/visitable.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ function appendQueryParams(path, queryParams) {
* @param {string} path - Full path of the route to visit
* @return {Descriptor}
*
* @throws Will throw an error if dynamic segments are not filled
* @throws Will throw an error if dynamic segments are not filled.
* Note: An error instance may contain a `cause.error` property
* with the original error thrown by an underlying test helper.
*/
export function visitable(path) {
return action(function (dynamicSegmentsAndQueryParams = {}) {
Expand All @@ -138,8 +140,10 @@ export function visitable(path) {

return getAdapter()
.visit(fullPath)
.catch(() => {
throw new Error(`Failed to visit URL '${fullPath}'`);
.catch((e) => {
throw new Error(`Failed to visit URL '${fullPath}': ${e.toString()}`, {
cause: e,
});
});
});
}
12 changes: 11 additions & 1 deletion test-app/tests/unit/-private/properties/visitable-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,21 @@ module('visitable', function (hooks) {
} catch (e) {
assert.strictEqual(
e?.toString(),
`Error: Failed to visit URL '/non-existing-url/value'
`Error: Failed to visit URL '/non-existing-url/value': UnrecognizedURLError: /non-existing-url/value
PageObject: 'page.foo("[object Object]")'
Selector: '.scope'`
);

const originalError = (e as any).cause.error;
assert.true(
originalError instanceof Error,
'`cause.error` is an instance of `Error`'
);

assert.strictEqual(originalError.name, 'UnrecognizedURLError');

assert.strictEqual(originalError.message, '/non-existing-url/value');
}
});
});
1 change: 1 addition & 0 deletions test-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "@tsconfig/ember/tsconfig.json",
"compilerOptions": {
"target": "es2022",
// The combination of `baseUrl` with `paths` allows Ember's classic package
// layout, which is not resolvable with the Node resolution algorithm, to
// work with TypeScript.
Expand Down

0 comments on commit ed51bb1

Please sign in to comment.