( componentInfo: ReactComponentInfo, )
| 14 | import {formatOwnerStack} from 'shared/ReactOwnerStackFrames'; |
| 15 | |
| 16 | export function getOwnerStackByComponentInfoInDev( |
| 17 | componentInfo: ReactComponentInfo, |
| 18 | ): string { |
| 19 | if (!__DEV__) { |
| 20 | return ''; |
| 21 | } |
| 22 | try { |
| 23 | let info = ''; |
| 24 | |
| 25 | // The owner stack of the current component will be where it was created, i.e. inside its owner. |
| 26 | // There's no actual name of the currently executing component. Instead, that is available |
| 27 | // on the regular stack that's currently executing. However, if there is no owner at all, then |
| 28 | // there's no stack frame so we add the name of the root component to the stack to know which |
| 29 | // component is currently executing. |
| 30 | if (!componentInfo.owner && typeof componentInfo.name === 'string') { |
| 31 | return describeBuiltInComponentFrame(componentInfo.name); |
| 32 | } |
| 33 | |
| 34 | let owner: void | null | ReactComponentInfo = componentInfo; |
| 35 | |
| 36 | while (owner) { |
| 37 | const ownerStack: ?Error = owner.debugStack; |
| 38 | if (ownerStack != null) { |
| 39 | // Server Component |
| 40 | owner = owner.owner; |
| 41 | if (owner) { |
| 42 | // TODO: Should we stash this somewhere for caching purposes? |
| 43 | info += '\n' + formatOwnerStack(ownerStack); |
| 44 | } |
| 45 | } else { |
| 46 | break; |
| 47 | } |
| 48 | } |
| 49 | return info; |
| 50 | } catch (x) { |
| 51 | return '\nError generating stack: ' + x.message + '\n' + x.stack; |
| 52 | } |
| 53 | } |
no test coverage detected