You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
2.6 KiB

4 years ago
  1. var inherits = require('inherits');
  2. function Reporter(options) {
  3. this._reporterState = {
  4. obj: null,
  5. path: [],
  6. options: options || {},
  7. errors: []
  8. };
  9. }
  10. exports.Reporter = Reporter;
  11. Reporter.prototype.isError = function isError(obj) {
  12. return obj instanceof ReporterError;
  13. };
  14. Reporter.prototype.save = function save() {
  15. var state = this._reporterState;
  16. return { obj: state.obj, pathLen: state.path.length };
  17. };
  18. Reporter.prototype.restore = function restore(data) {
  19. var state = this._reporterState;
  20. state.obj = data.obj;
  21. state.path = state.path.slice(0, data.pathLen);
  22. };
  23. Reporter.prototype.enterKey = function enterKey(key) {
  24. return this._reporterState.path.push(key);
  25. };
  26. Reporter.prototype.exitKey = function exitKey(index) {
  27. var state = this._reporterState;
  28. state.path = state.path.slice(0, index - 1);
  29. };
  30. Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
  31. var state = this._reporterState;
  32. this.exitKey(index);
  33. if (state.obj !== null)
  34. state.obj[key] = value;
  35. };
  36. Reporter.prototype.path = function path() {
  37. return this._reporterState.path.join('/');
  38. };
  39. Reporter.prototype.enterObject = function enterObject() {
  40. var state = this._reporterState;
  41. var prev = state.obj;
  42. state.obj = {};
  43. return prev;
  44. };
  45. Reporter.prototype.leaveObject = function leaveObject(prev) {
  46. var state = this._reporterState;
  47. var now = state.obj;
  48. state.obj = prev;
  49. return now;
  50. };
  51. Reporter.prototype.error = function error(msg) {
  52. var err;
  53. var state = this._reporterState;
  54. var inherited = msg instanceof ReporterError;
  55. if (inherited) {
  56. err = msg;
  57. } else {
  58. err = new ReporterError(state.path.map(function(elem) {
  59. return '[' + JSON.stringify(elem) + ']';
  60. }).join(''), msg.message || msg, msg.stack);
  61. }
  62. if (!state.options.partial)
  63. throw err;
  64. if (!inherited)
  65. state.errors.push(err);
  66. return err;
  67. };
  68. Reporter.prototype.wrapResult = function wrapResult(result) {
  69. var state = this._reporterState;
  70. if (!state.options.partial)
  71. return result;
  72. return {
  73. result: this.isError(result) ? null : result,
  74. errors: state.errors
  75. };
  76. };
  77. function ReporterError(path, msg) {
  78. this.path = path;
  79. this.rethrow(msg);
  80. };
  81. inherits(ReporterError, Error);
  82. ReporterError.prototype.rethrow = function rethrow(msg) {
  83. this.message = msg + ' at: ' + (this.path || '(shallow)');
  84. if (Error.captureStackTrace)
  85. Error.captureStackTrace(this, ReporterError);
  86. if (!this.stack) {
  87. try {
  88. // IE only adds stack when thrown
  89. throw new Error(this.message);
  90. } catch (e) {
  91. this.stack = e.stack;
  92. }
  93. }
  94. return this;
  95. };