Skip to content

Commit

Permalink
Add better Transition debugging information.
Browse files Browse the repository at this point in the history
Expose a few nice debugging tools when working with a transition:

```ts
interface Transition {
  /**
    In non-production builds, this function will return the stack that this Transition was
    created within. In production builds, this function will not be present.

    @method debugCreationStack
    @return string
  */
  debugCreationStack?: () => string | undefined;

  /**
    In non-production builds, this function will return the stack that this Transition was
    aborted within (or `undefined` if the Transition has not been aborted yet). In production
    builds, this function will not be present.

    @method debugAbortStack
    @return string
  */
  debugAbortStack?: () => string | undefined;

  /**
    In non-production builds, this property references the Transition that _this_ Transition
    was derived from or `undefined` if this transition did not derive from another. In
    production builds, this property will not be present.

    @Property debugPreviousTransition
    @type {Transition | undefined}
  */
  debugPreviousTransition: Maybe<Transition<T>>;
}
```

---

Note: I've confirmed that Ember's build pipeline properly replaces the
`if (DEBUG) {` bits with `true` and `false` as appropriate:

  ```js
  if (true
      /* DEBUG */
  ) {
    var _error = new Error(`Transition creation stack`);

    this.debugCreationStack = () => _error.stack;

    this.debugPreviousTransition = previousTransition;
  }
```
  • Loading branch information
rwjblue committed Sep 9, 2020
1 parent cfe549c commit c33fd6d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
49 changes: 49 additions & 0 deletions lib/router/transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import TransitionAborted, { ITransitionAbortedError } from './transition-aborted
import { OpaqueIntent } from './transition-intent';
import TransitionState, { TransitionError } from './transition-state';
import { log, promiseLabel } from './utils';
import { DEBUG } from '@glimmer/env';

export type OnFulfilled<T, TResult1> =
| ((value: T) => TResult1 | PromiseLike<TResult1>)
Expand Down Expand Up @@ -65,6 +66,35 @@ export default class Transition<T extends Route> implements Partial<Promise<T>>
isCausedByAbortingReplaceTransition = false;
_visibleQueryParams: Dict<unknown> = {};

/**
In non-production builds, this function will return the stack that this Transition was
created within. In production builds, this function will not be present.
@method debugCreationStack
@return string
*/
declare debugCreationStack?: () => string | undefined;

/**
In non-production builds, this function will return the stack that this Transition was
aborted within (or `undefined` if the Transition has not been aborted yet). In production
builds, this function will not be present.
@method debugAbortStack
@return string
*/
declare debugAbortStack?: () => string | undefined;

/**
In non-production builds, this property references the Transition that _this_ Transition
was derived from or `undefined` if this transition did not derive from another. In
production builds, this property will not be present.
@property debugPreviousTransition
@type {Transition | undefined}
*/
declare debugPreviousTransition: Maybe<Transition<T>>;

constructor(
router: Router<T>,
intent: Maybe<OpaqueIntent>,
Expand All @@ -86,6 +116,17 @@ export default class Transition<T extends Route> implements Partial<Promise<T>>
this.pivotHandler = undefined;
this.sequence = -1;

if (DEBUG) {
let error = new Error(`Transition creation stack`);

this.debugCreationStack = () => error.stack;

// not aborted yet, will be replaced when `this.isAborted` is set
this.debugAbortStack = () => undefined;

this.debugPreviousTransition = previousTransition;
}

if (error) {
this.promise = Promise.reject(error);
this.error = error;
Expand Down Expand Up @@ -250,9 +291,17 @@ export default class Transition<T extends Route> implements Partial<Promise<T>>
rollback() {
if (!this.isAborted) {
log(this.router, this.sequence, this.targetName + ': transition was aborted');

if (DEBUG) {
let error = new Error(`Transition aborted stack`);

this.debugAbortStack = () => error.stack;
}

if (this.intent !== undefined && this.intent !== null) {
this.intent.preTransitionState = this.router.state;
}

this.isAborted = true;
this.isActive = false;
this.router.activeTransition = undefined;
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"start": "ember server",
"test": "ember test"
},
"dependencies": {},
"dependencies": {
"@glimmer/env": "^0.1.7"
},
"devDependencies": {
"@babel/plugin-transform-modules-amd": "^7.10.5",
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@
exec-sh "^0.3.2"
minimist "^1.2.0"

"@glimmer/env@^0.1.7":
version "0.1.7"
resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07"
integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc=

"@iarna/toml@2.2.5":
version "2.2.5"
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c"
Expand Down

0 comments on commit c33fd6d

Please sign in to comment.