{"record":{"id":"cd73cc5588d79acf","repo":"emberjs/ember.js","slug":"transitionerror","errorCode":null,"errorMessage":"TransitionError","messagePattern":"TransitionError","errorType":"exception","errorClass":"TransitionError","httpStatus":null,"severity":"error","filePath":"packages/router_js/lib/transition-state.ts","lineNumber":26,"sourceCode":"\ninterface IParams {\n  [key: string]: unknown;\n}\n\nfunction handleError<R extends Route>(\n  currentState: TransitionState<R>,\n  transition: Transition<R>,\n  error: Error\n): never {\n  // This is the only possible\n  // reject value of TransitionState#resolve\n  let routeInfos = currentState.routeInfos;\n  let errorHandlerIndex =\n    transition.resolveIndex >= routeInfos.length ? routeInfos.length - 1 : transition.resolveIndex;\n\n  let wasAborted = transition.isAborted;\n\n  throw new TransitionError(\n    error,\n    currentState.routeInfos[errorHandlerIndex]!.route!,\n    wasAborted,\n    currentState\n  );\n}\n\nfunction resolveOneRouteInfo<R extends Route>(\n  currentState: TransitionState<R>,\n  transition: Transition<R>\n): void | Promise<void> {\n  if (transition.resolveIndex === currentState.routeInfos.length) {\n    // This is is the only possible\n    // fulfill value of TransitionState#resolve\n    return;\n  }\n\n  let routeInfo = currentState.routeInfos[transition.resolveIndex]!;","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/router_js/lib/transition-state.ts#L8-L44","documentation":"TransitionState.handleError wraps an error thrown during a transition (in a route hook like beforeModel/model/afterModel) in a TransitionError carrying the failing RouteInfo, whether the transition was aborted, and the state. The message is always 'TransitionError'; the original cause is on the `.cause`/error property. It signals the transition failed mid-flight at the given resolve index.","triggerScenarios":"Any route hook throws or rejects during transitionTo/handleURL; router handles it via handleError and rethrows as TransitionError.","commonSituations":"Model hooks rejecting on API failure; beforeModel redirects gone wrong; unhandled promise rejections in route lifecycle; assertion errors from guards.","solutions":["Inspect error.cause / the wrapped error to find the real failure.","Add error handling in route hooks (try/catch or .catch) or an application-level error route/action.","Handle the rejection where transitionTo is called: router.transitionTo(...).catch(fn).","Use error routes (this.route('error', { path: '*:' })) or route error actions to recover gracefully."],"exampleFix":"// before\nrouter.transitionTo('post', id); // unhandled rejection wraps the API failure\n// after\nrouter.transitionTo('post', id).catch((e) => {\n  console.error('transition failed:', e.cause ?? e);\n});","handlingStrategy":"try-catch","validationCode":"// Validate route-hook preconditions before transitioning\nasync function safeTransition(router, name, model) {\n  if (!model) return router.transitionTo('index');\n  return router.transitionTo(name, model);\n}","typeGuard":"function isTransitionError(e) { return e instanceof Error && e.message === 'TransitionError'; }","tryCatchPattern":"router.transitionTo('post', id).catch(e => {\n  if (isTransitionError(e)) {\n    const cause = e.cause ?? e.error;\n    console.error('transition hook failed:', cause);\n    router.transitionTo('error');\n  }\n});","preventionTips":["Add error actions on routes (route's `actions.error`) for graceful recovery.","Wrap model-hook fetches with .catch and redirect on failure.","Always attach .catch to transitionTo/handleURL calls.","Define an application-level error route."],"tags":["routing","transition","ember"],"backgroundTag":"route-transition-failed","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}