Skip to content

Commit 318f345

Browse files
committed
fix: checkContext better error message
1 parent eb2be74 commit 318f345

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

docs/migrating-from-feathers-hooks-common.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,46 @@ The old `cache` hook only worked for `get` requests and did not work with varyin
4646

4747
The new `cache` hook caches `get` and `find` requests and considers the `params` object when caching. This means that if you call the same `get` or `find` request with different `params`, it will cache each unique request separately.
4848

49+
## `checkContext`
50+
51+
The `checkContext` utility has been updated with an options object syntax and now supports **TypeScript type narrowing**. After calling `checkContext`, the compiler automatically narrows `context.type`, `context.method`, and `context.path` based on the options you pass.
52+
53+
The old positional arguments still work but the options object is recommended:
54+
55+
```ts
56+
// old
57+
import { checkContext } from "feathers-hooks-common";
58+
59+
checkContext(context, "before", ["create", "patch"], "myHook");
60+
61+
// new (recommended: options object with type narrowing)
62+
import { checkContext } from "feathers-utils/utils";
63+
64+
checkContext(context, {
65+
type: "before",
66+
method: ["create", "patch"],
67+
label: "myHook",
68+
});
69+
70+
// After checkContext, TypeScript narrows the types:
71+
context.type; // 'before'
72+
context.method; // 'create' | 'patch'
73+
```
74+
75+
You can also narrow by `path`, which was not available in the old API:
76+
77+
```ts
78+
checkContext(context, {
79+
type: ["before", "around"],
80+
method: ["create", "patch"],
81+
path: "users",
82+
});
83+
84+
context.type; // 'before' | 'around'
85+
context.method; // 'create' | 'patch'
86+
context.path; // 'users'
87+
```
88+
4989
## `callingParams`
5090

5191
The `callingParams` utility was removed. If you need it please reach out to us in this [github issue](https://github.com/feathersjs/feathers-utils/issues/1).

src/utils/check-context/check-context.util.test.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,29 @@ describe('util checkContext', () => {
164164
type: 'before',
165165
label: 'myHook',
166166
}),
167-
).toThrow("The 'myHook' hook has invalid context.")
167+
).toThrow(
168+
"The 'myHook' hook has invalid context (type: expected 'before' but got 'after').",
169+
)
168170
})
169171

170172
it('uses default label when not provided', () => {
171173
expect(() =>
172174
checkContext(make('after', 'create'), { type: 'before' }),
173-
).toThrow("The 'anonymous' hook has invalid context.")
175+
).toThrow(
176+
"The 'anonymous' hook has invalid context (type: expected 'before' but got 'after').",
177+
)
178+
})
179+
180+
it('shows multiple mismatches in error message', () => {
181+
expect(() =>
182+
checkContext(make('after', 'patch'), {
183+
type: ['before', 'around'],
184+
method: 'create',
185+
label: 'myHook',
186+
}),
187+
).toThrow(
188+
"The 'myHook' hook has invalid context (type: expected 'before' | 'around' but got 'after', method: expected 'create' but got 'patch').",
189+
)
174190
})
175191
})
176192
})

src/utils/check-context/check-context.util.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,26 @@ export function checkContext<H extends HookContext = HookContext>(
9292
}
9393

9494
if (!isContext(options)(context)) {
95-
throw new Error(`The '${hookLabel}' hook has invalid context.`)
95+
const details: string[] = []
96+
97+
if (options.type != null) {
98+
details.push(
99+
`type: expected '${Array.isArray(options.type) ? options.type.join("' | '") : options.type}' but got '${context.type}'`,
100+
)
101+
}
102+
if (options.method != null) {
103+
details.push(
104+
`method: expected '${Array.isArray(options.method) ? options.method.join("' | '") : options.method}' but got '${context.method}'`,
105+
)
106+
}
107+
if (options.path != null) {
108+
details.push(
109+
`path: expected '${Array.isArray(options.path) ? options.path.join("' | '") : options.path}' but got '${context.path}'`,
110+
)
111+
}
112+
113+
throw new Error(
114+
`The '${hookLabel}' hook has invalid context (${details.join(', ')}).`,
115+
)
96116
}
97117
}

0 commit comments

Comments
 (0)