LogBoxLog.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow strict-local
  8. * @format
  9. */
  10. 'use strict';
  11. import * as LogBoxSymbolication from './LogBoxSymbolication';
  12. import type {
  13. Category,
  14. Message,
  15. ComponentStack,
  16. CodeFrame,
  17. } from './parseLogBoxLog';
  18. import type {Stack} from './LogBoxSymbolication';
  19. type SymbolicationStatus = 'NONE' | 'PENDING' | 'COMPLETE' | 'FAILED';
  20. export type LogLevel = 'warn' | 'error' | 'fatal' | 'syntax';
  21. export type LogBoxLogData = $ReadOnly<{|
  22. level: LogLevel,
  23. type?: ?string,
  24. message: Message,
  25. stack: Stack,
  26. category: string,
  27. componentStack: ComponentStack,
  28. codeFrame?: ?CodeFrame,
  29. isComponentError: boolean,
  30. |}>;
  31. class LogBoxLog {
  32. message: Message;
  33. type: ?string;
  34. category: Category;
  35. componentStack: ComponentStack;
  36. stack: Stack;
  37. count: number;
  38. level: LogLevel;
  39. codeFrame: ?CodeFrame;
  40. isComponentError: boolean;
  41. symbolicated:
  42. | $ReadOnly<{|error: null, stack: null, status: 'NONE'|}>
  43. | $ReadOnly<{|error: null, stack: null, status: 'PENDING'|}>
  44. | $ReadOnly<{|error: null, stack: Stack, status: 'COMPLETE'|}>
  45. | $ReadOnly<{|error: Error, stack: null, status: 'FAILED'|}> = {
  46. error: null,
  47. stack: null,
  48. status: 'NONE',
  49. };
  50. constructor(data: LogBoxLogData) {
  51. this.level = data.level;
  52. this.type = data.type;
  53. this.message = data.message;
  54. this.stack = data.stack;
  55. this.category = data.category;
  56. this.componentStack = data.componentStack;
  57. this.codeFrame = data.codeFrame;
  58. this.isComponentError = data.isComponentError;
  59. this.count = 1;
  60. }
  61. incrementCount(): void {
  62. this.count += 1;
  63. }
  64. getAvailableStack(): Stack {
  65. return this.symbolicated.status === 'COMPLETE'
  66. ? this.symbolicated.stack
  67. : this.stack;
  68. }
  69. retrySymbolicate(callback?: (status: SymbolicationStatus) => void): void {
  70. if (this.symbolicated.status !== 'COMPLETE') {
  71. LogBoxSymbolication.deleteStack(this.stack);
  72. this.handleSymbolicate(callback);
  73. }
  74. }
  75. symbolicate(callback?: (status: SymbolicationStatus) => void): void {
  76. if (this.symbolicated.status === 'NONE') {
  77. this.handleSymbolicate(callback);
  78. }
  79. }
  80. handleSymbolicate(callback?: (status: SymbolicationStatus) => void): void {
  81. if (this.symbolicated.status !== 'PENDING') {
  82. this.updateStatus(null, null, null, callback);
  83. LogBoxSymbolication.symbolicate(this.stack).then(
  84. data => {
  85. this.updateStatus(null, data?.stack, data?.codeFrame, callback);
  86. },
  87. error => {
  88. this.updateStatus(error, null, null, callback);
  89. },
  90. );
  91. }
  92. }
  93. updateStatus(
  94. error: ?Error,
  95. stack: ?Stack,
  96. codeFrame: ?CodeFrame,
  97. callback?: (status: SymbolicationStatus) => void,
  98. ): void {
  99. const lastStatus = this.symbolicated.status;
  100. if (error != null) {
  101. this.symbolicated = {
  102. error,
  103. stack: null,
  104. status: 'FAILED',
  105. };
  106. } else if (stack != null) {
  107. if (codeFrame) {
  108. this.codeFrame = codeFrame;
  109. }
  110. this.symbolicated = {
  111. error: null,
  112. stack,
  113. status: 'COMPLETE',
  114. };
  115. } else {
  116. this.symbolicated = {
  117. error: null,
  118. stack: null,
  119. status: 'PENDING',
  120. };
  121. }
  122. if (callback && lastStatus !== this.symbolicated.status) {
  123. callback(this.symbolicated.status);
  124. }
  125. }
  126. }
  127. export default LogBoxLog;