Skip to content

Commit d111c2c

Browse files
fix(vue): Remove deprecated next() callback from router instrumentation
1 parent 11e5412 commit d111c2c

2 files changed

Lines changed: 19 additions & 44 deletions

File tree

packages/vue/src/router.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export type Route = {
2929

3030
interface VueRouter {
3131
onError: (fn: (err: Error) => void) => void;
32-
beforeEach: (fn: (to: Route, from: Route, next?: () => void) => void) => void;
32+
beforeEach: (fn: (to: Route, from: Route) => void) => void;
3333
}
3434

3535
/**
@@ -54,7 +54,7 @@ export function instrumentVueRouter(
5454

5555
router.onError(error => captureException(error, { mechanism: { handled: false } }));
5656

57-
router.beforeEach((to, _from, next) => {
57+
router.beforeEach((to, _from) => {
5858
// We avoid trying to re-fetch the page load span when we know we already handled it the first time
5959
const activePageLoadSpan = !hasHandledFirstPageLoad ? getActivePageLoadSpan() : undefined;
6060

@@ -115,13 +115,6 @@ export function instrumentVueRouter(
115115
},
116116
});
117117
}
118-
119-
// Vue Router 4 no longer exposes the `next` function, so we need to
120-
// check if it's available before calling it.
121-
// `next` needs to be called in Vue Router 3 so that the hook is resolved.
122-
if (next) {
123-
next();
124-
}
125118
});
126119
}
127120

packages/vue/test/router.test.ts

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@ vi.mock('@sentry/core', async () => {
2323

2424
const mockVueRouter = {
2525
onError: vi.fn<[(error: Error) => void]>(),
26-
beforeEach: vi.fn<[(from: Route, to: Route, next?: () => void) => void]>(),
26+
beforeEach: vi.fn<[(from: Route, to: Route) => void]>(),
2727
};
2828

29-
const mockNext = vi.fn();
30-
3129
const testRoutes: Record<string, Route> = {
3230
initialPageloadRoute: { matched: [], params: {}, path: '', query: {} },
3331
normalRoute1: {
@@ -118,8 +116,8 @@ describe('instrumentVueRouter()', () => {
118116

119117
const from = testRoutes[fromKey]!;
120118
const to = testRoutes[toKey]!;
121-
beforeEachCallback(to, testRoutes['initialPageloadRoute']!, mockNext); // fake initial pageload
122-
beforeEachCallback(to, from, mockNext);
119+
beforeEachCallback(to, testRoutes['initialPageloadRoute']!); // fake initial pageload
120+
beforeEachCallback(to, from);
123121

124122
expect(mockStartSpan).toHaveBeenCalledTimes(2);
125123
expect(mockStartSpan).toHaveBeenLastCalledWith({
@@ -131,8 +129,6 @@ describe('instrumentVueRouter()', () => {
131129
},
132130
op: 'navigation',
133131
});
134-
135-
expect(mockNext).toHaveBeenCalledTimes(2);
136132
},
137133
);
138134

@@ -171,7 +167,7 @@ describe('instrumentVueRouter()', () => {
171167
const from = testRoutes[fromKey]!;
172168
const to = testRoutes[toKey]!;
173169

174-
beforeEachCallback(to, from, mockNext);
170+
beforeEachCallback(to, from);
175171
expect(mockVueRouter.beforeEach).toHaveBeenCalledTimes(1);
176172

177173
expect(mockRootSpan.updateName).toHaveBeenCalledWith(transactionName);
@@ -180,8 +176,6 @@ describe('instrumentVueRouter()', () => {
180176
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.vue',
181177
...getAttributesForRoute(to),
182178
});
183-
184-
expect(mockNext).toHaveBeenCalledTimes(1);
185179
},
186180
);
187181

@@ -198,8 +192,8 @@ describe('instrumentVueRouter()', () => {
198192

199193
const from = testRoutes.normalRoute1!;
200194
const to = testRoutes.namedRoute!;
201-
beforeEachCallback(to, testRoutes['initialPageloadRoute']!, mockNext); // fake initial pageload
202-
beforeEachCallback(to, from, mockNext);
195+
beforeEachCallback(to, testRoutes['initialPageloadRoute']!); // fake initial pageload
196+
beforeEachCallback(to, from);
203197

204198
// first startTx call happens when the instrumentation is initialized (for pageloads)
205199
expect(mockStartSpan).toHaveBeenLastCalledWith({
@@ -226,8 +220,8 @@ describe('instrumentVueRouter()', () => {
226220

227221
const from = testRoutes.normalRoute1!;
228222
const to = testRoutes.namedRoute!;
229-
beforeEachCallback(to, testRoutes['initialPageloadRoute']!, mockNext); // fake initial pageload
230-
beforeEachCallback(to, from, mockNext);
223+
beforeEachCallback(to, testRoutes['initialPageloadRoute']!); // fake initial pageload
224+
beforeEachCallback(to, from);
231225

232226
// first startTx call happens when the instrumentation is initialized (for pageloads)
233227
expect(mockStartSpan).toHaveBeenLastCalledWith({
@@ -284,7 +278,7 @@ describe('instrumentVueRouter()', () => {
284278
const to = testRoutes['normalRoute1']!;
285279
const from = testRoutes['initialPageloadRoute']!;
286280

287-
beforeEachCallback(to, from, mockNext);
281+
beforeEachCallback(to, from);
288282

289283
expect(mockVueRouter.beforeEach).toHaveBeenCalledTimes(1);
290284

@@ -318,7 +312,7 @@ describe('instrumentVueRouter()', () => {
318312
const from = testRoutes['initialPageloadRoute']!;
319313
const to = testRoutes['normalRoute1']!;
320314

321-
beforeEachCallback(to, from, mockNext);
315+
beforeEachCallback(to, from);
322316

323317
expect(scopeSetTransactionNameSpy).toHaveBeenCalledTimes(1);
324318
expect(scopeSetTransactionNameSpy).toHaveBeenCalledWith('/books/:bookId/chapter/:chapterId');
@@ -357,7 +351,7 @@ describe('instrumentVueRouter()', () => {
357351
expect(mockVueRouter.beforeEach).toHaveBeenCalledTimes(1);
358352

359353
const beforeEachCallback = mockVueRouter.beforeEach.mock.calls[0]![0]!;
360-
beforeEachCallback(testRoutes['normalRoute1']!, testRoutes['initialPageloadRoute']!, mockNext);
354+
beforeEachCallback(testRoutes['normalRoute1']!, testRoutes['initialPageloadRoute']!);
361355

362356
expect(mockRootSpan.updateName).toHaveBeenCalledTimes(expectedCallsAmount);
363357
expect(mockStartSpan).not.toHaveBeenCalled();
@@ -381,14 +375,14 @@ describe('instrumentVueRouter()', () => {
381375
expect(mockVueRouter.beforeEach).toHaveBeenCalledTimes(1);
382376

383377
const beforeEachCallback = mockVueRouter.beforeEach.mock.calls[0]![0]!;
384-
beforeEachCallback(testRoutes['normalRoute1']!, testRoutes['initialPageloadRoute']!, mockNext); // fake initial pageload
385-
beforeEachCallback(testRoutes['normalRoute2']!, testRoutes['normalRoute1']!, mockNext);
378+
beforeEachCallback(testRoutes['normalRoute1']!, testRoutes['initialPageloadRoute']!); // fake initial pageload
379+
beforeEachCallback(testRoutes['normalRoute2']!, testRoutes['normalRoute1']!);
386380

387381
expect(mockStartSpan).toHaveBeenCalledTimes(expectedCallsAmount);
388382
},
389383
);
390384

391-
it("doesn't throw when `next` is not available in the beforeEach callback (Vue Router 4)", () => {
385+
it('does not declare a third parameter to avoid Vue Router next() deprecation warning', () => {
392386
const mockStartSpan = vi.fn().mockReturnValue(MOCK_SPAN);
393387
instrumentVueRouter(
394388
mockVueRouter,
@@ -398,21 +392,9 @@ describe('instrumentVueRouter()', () => {
398392

399393
const beforeEachCallback = mockVueRouter.beforeEach.mock.calls[0]![0]!;
400394

401-
const from = testRoutes.normalRoute1!;
402-
const to = testRoutes.namedRoute!;
403-
beforeEachCallback(to, testRoutes['initialPageloadRoute']!, mockNext); // fake initial pageload
404-
beforeEachCallback(to, from, undefined);
405-
406-
// first startTx call happens when the instrumentation is initialized (for pageloads)
407-
expect(mockStartSpan).toHaveBeenLastCalledWith({
408-
name: '/login',
409-
attributes: {
410-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.vue',
411-
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
412-
...getAttributesForRoute(to),
413-
},
414-
op: 'navigation',
415-
});
395+
// Vue Router uses Function.length to detect whether the guard uses the legacy
396+
// `next` callback. Guards with < 3 params use the modern return-based pattern.
397+
expect(beforeEachCallback.length).toBeLessThan(3);
416398
});
417399
});
418400

0 commit comments

Comments
 (0)