JavaScriptException.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #nullable enable
  2. using System;
  3. using Esprima;
  4. using Jint.Native;
  5. using Jint.Native.Error;
  6. using Jint.Native.Object;
  7. using Jint.Pooling;
  8. namespace Jint.Runtime
  9. {
  10. public class JavaScriptException : JintException
  11. {
  12. private string? _callStack;
  13. public JavaScriptException(ErrorConstructor errorConstructor) : base("")
  14. {
  15. Error = errorConstructor.Construct(Arguments.Empty);
  16. }
  17. public JavaScriptException(ErrorConstructor errorConstructor, string? message, Exception? innerException)
  18. : base(message, innerException)
  19. {
  20. Error = errorConstructor.Construct(new JsValue[] { message });
  21. }
  22. public JavaScriptException(ErrorConstructor errorConstructor, string? message)
  23. : base(message)
  24. {
  25. Error = errorConstructor.Construct(new JsValue[] { message });
  26. }
  27. public JavaScriptException(JsValue error)
  28. {
  29. Error = error;
  30. }
  31. // Copy constructors
  32. public JavaScriptException(JavaScriptException exception, Exception? innerException) : base(exception.Message, exception.InnerException)
  33. {
  34. Error = exception.Error;
  35. Location = exception.Location;
  36. }
  37. public JavaScriptException(JavaScriptException exception) : base(exception.Message)
  38. {
  39. Error = exception.Error;
  40. Location = exception.Location;
  41. }
  42. internal JavaScriptException SetLocation(Location location)
  43. {
  44. Location = location;
  45. return this;
  46. }
  47. internal JavaScriptException SetCallstack(Engine engine, Location location)
  48. {
  49. Location = location;
  50. var value = engine.CallStack.BuildCallStackString(location);
  51. _callStack = value;
  52. if (Error.IsObject())
  53. {
  54. Error.AsObject()
  55. .FastAddProperty(CommonProperties.Stack, new JsString(value), false, false, false);
  56. }
  57. return this;
  58. }
  59. private string? GetErrorMessage()
  60. {
  61. if (Error is ObjectInstance oi)
  62. {
  63. return oi.Get(CommonProperties.Message).ToString();
  64. }
  65. return null;
  66. }
  67. public JsValue Error { get; }
  68. public override string Message => GetErrorMessage() ?? TypeConverter.ToString(Error);
  69. /// <summary>
  70. /// Returns the call stack of the exception. Requires that engine was built using
  71. /// <see cref="Options.CollectStackTrace"/>.
  72. /// </summary>
  73. public override string? StackTrace
  74. {
  75. get
  76. {
  77. if (_callStack is not null)
  78. {
  79. return _callStack;
  80. }
  81. if (Error is not ObjectInstance oi)
  82. {
  83. return null;
  84. }
  85. var callstack = oi.Get(CommonProperties.Stack, Error);
  86. return callstack.IsUndefined()
  87. ? null
  88. : callstack.AsString();
  89. }
  90. }
  91. public Location Location { get; protected set; }
  92. public int LineNumber => Location.Start.Line;
  93. public int Column => Location.Start.Column;
  94. public override string ToString()
  95. {
  96. // adapted custom version as logic differs between full framework and .NET Core
  97. var className = GetType().ToString();
  98. var message = Message;
  99. var innerExceptionString = InnerException?.ToString() ?? "";
  100. const string endOfInnerExceptionResource = "--- End of inner exception stack trace ---";
  101. var stackTrace = StackTrace;
  102. using var rent = StringBuilderPool.Rent();
  103. var sb = rent.Builder;
  104. sb.Append(className);
  105. if (!string.IsNullOrEmpty(message))
  106. {
  107. sb.Append(": ");
  108. sb.Append(message);
  109. }
  110. if (InnerException != null)
  111. {
  112. sb.Append(Environment.NewLine);
  113. sb.Append(" ---> ");
  114. sb.Append(innerExceptionString);
  115. sb.Append(Environment.NewLine);
  116. sb.Append(" ");
  117. sb.Append(endOfInnerExceptionResource);
  118. }
  119. if (stackTrace != null)
  120. {
  121. sb.Append(Environment.NewLine);
  122. sb.Append(stackTrace);
  123. }
  124. return rent.ToString();
  125. }
  126. }
  127. }