error.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. export class IdlError extends Error {}
  2. // An error from a user defined program.
  3. export class ProgramError extends Error {
  4. constructor(readonly code: number, readonly msg: string, ...params: any[]) {
  5. super(...params);
  6. }
  7. public static parse(
  8. err: any,
  9. idlErrors: Map<number, string>
  10. ): ProgramError | null {
  11. // TODO: don't rely on the error string. web3.js should preserve the error
  12. // code information instead of giving us an untyped string.
  13. let components = err.toString().split("custom program error: ");
  14. if (components.length !== 2) {
  15. return null;
  16. }
  17. let errorCode: number;
  18. try {
  19. errorCode = parseInt(components[1]);
  20. } catch (parseErr) {
  21. return null;
  22. }
  23. // Parse user error.
  24. let errorMsg = idlErrors.get(errorCode);
  25. if (errorMsg !== undefined) {
  26. return new ProgramError(errorCode, errorMsg);
  27. }
  28. // Parse framework internal error.
  29. errorMsg = LangErrorMessage.get(errorCode);
  30. if (errorMsg !== undefined) {
  31. return new ProgramError(errorCode, errorMsg);
  32. }
  33. // Unable to parse the error. Just return the untranslated error.
  34. return null;
  35. }
  36. public toString(): string {
  37. return this.msg;
  38. }
  39. }
  40. const LangErrorCode = {
  41. // Instructions.
  42. InstructionMissing: 100,
  43. InstructionFallbackNotFound: 101,
  44. InstructionDidNotDeserialize: 102,
  45. InstructionDidNotSerialize: 103,
  46. // IDL instructions.
  47. IdlInstructionStub: 120,
  48. IdlInstructionInvalidProgram: 121,
  49. // Constraints.
  50. ConstraintMut: 140,
  51. ConstraintBelongsTo: 141,
  52. ConstraintSigner: 142,
  53. ConstraintRaw: 143,
  54. ConstraintOwner: 144,
  55. ConstraintRentExempt: 145,
  56. ConstraintSeeds: 146,
  57. ConstraintExecutable: 147,
  58. ConstraintState: 148,
  59. ConstraintAssociated: 149,
  60. ConstraintAssociatedInit: 150,
  61. ConstraintClose: 151,
  62. // Accounts.
  63. AccountDiscriminatorAlreadySet: 160,
  64. AccountDiscriminatorNotFound: 161,
  65. AccountDiscriminatorMismatch: 162,
  66. AccountDidNotDeserialize: 163,
  67. AccountDidNotSerialize: 164,
  68. AccountNotEnoughKeys: 165,
  69. AccountNotMutable: 166,
  70. AccountNotProgramOwned: 167,
  71. // State.
  72. StateInvalidAddress: 180,
  73. // Used for APIs that shouldn't be used anymore.
  74. Deprecated: 299,
  75. };
  76. const LangErrorMessage = new Map([
  77. // Instructions.
  78. [
  79. LangErrorCode.InstructionMissing,
  80. "8 byte instruction identifier not provided",
  81. ],
  82. [
  83. LangErrorCode.InstructionFallbackNotFound,
  84. "Fallback functions are not supported",
  85. ],
  86. [
  87. LangErrorCode.InstructionDidNotDeserialize,
  88. "The program could not deserialize the given instruction",
  89. ],
  90. [
  91. LangErrorCode.InstructionDidNotSerialize,
  92. "The program could not serialize the given instruction",
  93. ],
  94. // Idl instructions.
  95. [
  96. LangErrorCode.IdlInstructionStub,
  97. "The program was compiled without idl instructions",
  98. ],
  99. [
  100. LangErrorCode.IdlInstructionInvalidProgram,
  101. "The transaction was given an invalid program for the IDL instruction",
  102. ],
  103. // Constraints.
  104. [LangErrorCode.ConstraintMut, "A mut constraint was violated"],
  105. [LangErrorCode.ConstraintBelongsTo, "A belongs_to constraint was violated"],
  106. [LangErrorCode.ConstraintSigner, "A signer constraint was violated"],
  107. [LangErrorCode.ConstraintRaw, "A raw constraint as violated"],
  108. [LangErrorCode.ConstraintOwner, "An owner constraint was violated"],
  109. [LangErrorCode.ConstraintRentExempt, "A rent exempt constraint was violated"],
  110. [LangErrorCode.ConstraintSeeds, "A seeds constraint was violated"],
  111. [LangErrorCode.ConstraintExecutable, "An executable constraint was violated"],
  112. [LangErrorCode.ConstraintState, "A state constraint was violated"],
  113. [LangErrorCode.ConstraintAssociated, "An associated constraint was violated"],
  114. [
  115. LangErrorCode.ConstraintAssociatedInit,
  116. "An associated init constraint was violated",
  117. ],
  118. [LangErrorCode.ConstraintClose, "A close constraint was violated"],
  119. // Accounts.
  120. [
  121. LangErrorCode.AccountDiscriminatorAlreadySet,
  122. "The account discriminator was already set on this account",
  123. ],
  124. [
  125. LangErrorCode.AccountDiscriminatorNotFound,
  126. "No 8 byte discriminator was found on the account",
  127. ],
  128. [
  129. LangErrorCode.AccountDiscriminatorMismatch,
  130. "8 byte discriminator did not match what was expected",
  131. ],
  132. [LangErrorCode.AccountDidNotDeserialize, "Failed to deserialize the account"],
  133. [LangErrorCode.AccountDidNotSerialize, "Failed to serialize the account"],
  134. [
  135. LangErrorCode.AccountNotEnoughKeys,
  136. "Not enough account keys given to the instruction",
  137. ],
  138. [LangErrorCode.AccountNotMutable, "The given account is not mutable"],
  139. [
  140. LangErrorCode.AccountNotProgramOwned,
  141. "The given account is not owned by the executing program",
  142. ],
  143. // State.
  144. [
  145. LangErrorCode.StateInvalidAddress,
  146. "The given state account does not have the correct address",
  147. ],
  148. // Misc.
  149. [
  150. LangErrorCode.Deprecated,
  151. "The API being used is deprecated and should no longer be used",
  152. ],
  153. ]);