error.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. use anchor_lang::error_code;
  2. use borsh::maybestd::io::Error as BorshIoError;
  3. use solana_program::{program_error::ProgramError, pubkey::Pubkey};
  4. use std::fmt::{Debug, Display};
  5. use std::num::TryFromIntError;
  6. /// The starting point for user defined error codes.
  7. pub const ERROR_CODE_OFFSET: u32 = 6000;
  8. /// Error codes that can be returned by internal framework code.
  9. ///
  10. /// - >= 100 Instruction error codes
  11. /// - >= 1000 IDL error codes
  12. /// - >= 2000 constraint error codes
  13. /// - >= 3000 account error codes
  14. /// - >= 4100 misc error codes
  15. /// - = 5000 deprecated error code
  16. ///
  17. /// The starting point for user-defined errors is defined
  18. /// by the [ERROR_CODE_OFFSET](crate::error::ERROR_CODE_OFFSET).
  19. #[error_code(offset = 0)]
  20. pub enum ErrorCode {
  21. // Instructions
  22. /// 100 - Instruction discriminator not provided
  23. #[msg("Instruction discriminator not provided")]
  24. InstructionMissing = 100,
  25. /// 101 - Fallback functions are not supported
  26. #[msg("Fallback functions are not supported")]
  27. InstructionFallbackNotFound,
  28. /// 102 - The program could not deserialize the given instruction
  29. #[msg("The program could not deserialize the given instruction")]
  30. InstructionDidNotDeserialize,
  31. /// 103 - The program could not serialize the given instruction
  32. #[msg("The program could not serialize the given instruction")]
  33. InstructionDidNotSerialize,
  34. // IDL instructions
  35. /// 1000 - The program was compiled without idl instructions
  36. #[msg("The program was compiled without idl instructions")]
  37. IdlInstructionStub = 1000,
  38. /// 1001 - Invalid program given to the IDL instruction
  39. #[msg("Invalid program given to the IDL instruction")]
  40. IdlInstructionInvalidProgram,
  41. /// 1002 - IDL Account must be empty in order to resize
  42. #[msg("IDL account must be empty in order to resize, try closing first")]
  43. IdlAccountNotEmpty,
  44. // Event instructions
  45. /// 1500 - The program was compiled without `event-cpi` feature
  46. #[msg("The program was compiled without `event-cpi` feature")]
  47. EventInstructionStub = 1500,
  48. // Constraints
  49. /// 2000 - A mut constraint was violated
  50. #[msg("A mut constraint was violated")]
  51. ConstraintMut = 2000,
  52. /// 2001 - A has one constraint was violated
  53. #[msg("A has one constraint was violated")]
  54. ConstraintHasOne,
  55. /// 2002 - A signer constraint was violated
  56. #[msg("A signer constraint was violated")]
  57. ConstraintSigner,
  58. /// 2003 - A raw constraint was violated
  59. #[msg("A raw constraint was violated")]
  60. ConstraintRaw,
  61. /// 2004 - An owner constraint was violated
  62. #[msg("An owner constraint was violated")]
  63. ConstraintOwner,
  64. /// 2005 - A rent exemption constraint was violated
  65. #[msg("A rent exemption constraint was violated")]
  66. ConstraintRentExempt,
  67. /// 2006 - A seeds constraint was violated
  68. #[msg("A seeds constraint was violated")]
  69. ConstraintSeeds,
  70. /// 2007 - An executable constraint was violated
  71. #[msg("An executable constraint was violated")]
  72. ConstraintExecutable,
  73. /// 2008 - Deprecated Error, feel free to replace with something else
  74. #[msg("Deprecated Error, feel free to replace with something else")]
  75. ConstraintState,
  76. /// 2009 - An associated constraint was violated
  77. #[msg("An associated constraint was violated")]
  78. ConstraintAssociated,
  79. /// 2010 - An associated init constraint was violated
  80. #[msg("An associated init constraint was violated")]
  81. ConstraintAssociatedInit,
  82. /// 2011 - A close constraint was violated
  83. #[msg("A close constraint was violated")]
  84. ConstraintClose,
  85. /// 2012 - An address constraint was violated
  86. #[msg("An address constraint was violated")]
  87. ConstraintAddress,
  88. /// 2013 - Expected zero account discriminant
  89. #[msg("Expected zero account discriminant")]
  90. ConstraintZero,
  91. /// 2014 - A token mint constraint was violated
  92. #[msg("A token mint constraint was violated")]
  93. ConstraintTokenMint,
  94. /// 2015 - A token owner constraint was violated
  95. #[msg("A token owner constraint was violated")]
  96. ConstraintTokenOwner,
  97. /// The mint mint is intentional -> a mint authority for the mint.
  98. ///
  99. /// 2016 - A mint mint authority constraint was violated
  100. #[msg("A mint mint authority constraint was violated")]
  101. ConstraintMintMintAuthority,
  102. /// 2017 - A mint freeze authority constraint was violated
  103. #[msg("A mint freeze authority constraint was violated")]
  104. ConstraintMintFreezeAuthority,
  105. /// 2018 - A mint decimals constraint was violated
  106. #[msg("A mint decimals constraint was violated")]
  107. ConstraintMintDecimals,
  108. /// 2019 - A space constraint was violated
  109. #[msg("A space constraint was violated")]
  110. ConstraintSpace,
  111. /// 2020 - A required account for the constraint is None
  112. #[msg("A required account for the constraint is None")]
  113. ConstraintAccountIsNone,
  114. /// The token token is intentional -> a token program for the token account.
  115. ///
  116. /// 2021 - A token account token program constraint was violated
  117. #[msg("A token account token program constraint was violated")]
  118. ConstraintTokenTokenProgram,
  119. /// 2022 - A mint token program constraint was violated
  120. #[msg("A mint token program constraint was violated")]
  121. ConstraintMintTokenProgram,
  122. /// 2023 - A mint token program constraint was violated
  123. #[msg("An associated token account token program constraint was violated")]
  124. ConstraintAssociatedTokenTokenProgram,
  125. /// Extension constraints
  126. ///
  127. /// 2024 - A group pointer extension constraint was violated
  128. #[msg("A group pointer extension constraint was violated")]
  129. ConstraintMintGroupPointerExtension,
  130. /// 2025 - A group pointer extension authority constraint was violated
  131. #[msg("A group pointer extension authority constraint was violated")]
  132. ConstraintMintGroupPointerExtensionAuthority,
  133. /// 2026 - A group pointer extension group address constraint was violated
  134. #[msg("A group pointer extension group address constraint was violated")]
  135. ConstraintMintGroupPointerExtensionGroupAddress,
  136. /// 2027 - A group member pointer extension constraint was violated
  137. #[msg("A group member pointer extension constraint was violated")]
  138. ConstraintMintGroupMemberPointerExtension,
  139. /// 2028 - A group member pointer extension authority constraint was violated
  140. #[msg("A group member pointer extension authority constraint was violated")]
  141. ConstraintMintGroupMemberPointerExtensionAuthority,
  142. /// 2029 - A group member pointer extension member address constraint was violated
  143. #[msg("A group member pointer extension group address constraint was violated")]
  144. ConstraintMintGroupMemberPointerExtensionMemberAddress,
  145. /// 2030 - A metadata pointer extension constraint was violated
  146. #[msg("A metadata pointer extension constraint was violated")]
  147. ConstraintMintMetadataPointerExtension,
  148. /// 2031 - A metadata pointer extension authority constraint was violated
  149. #[msg("A metadata pointer extension authority constraint was violated")]
  150. ConstraintMintMetadataPointerExtensionAuthority,
  151. /// 2032 - A metadata pointer extension metadata address constraint was violated
  152. #[msg("A metadata pointer extension metadata address constraint was violated")]
  153. ConstraintMintMetadataPointerExtensionMetadataAddress,
  154. /// 2033 - A close authority extension constraint was violated
  155. #[msg("A close authority constraint was violated")]
  156. ConstraintMintCloseAuthorityExtension,
  157. /// 2034 - A close authority extension authority constraint was violated
  158. #[msg("A close authority extension authority constraint was violated")]
  159. ConstraintMintCloseAuthorityExtensionAuthority,
  160. /// 2035 - A permanent delegate extension constraint was violated
  161. #[msg("A permanent delegate extension constraint was violated")]
  162. ConstraintMintPermanentDelegateExtension,
  163. /// 2036 - A permanent delegate extension authority constraint was violated
  164. #[msg("A permanent delegate extension delegate constraint was violated")]
  165. ConstraintMintPermanentDelegateExtensionDelegate,
  166. /// 2037 - A transfer hook extension constraint was violated
  167. #[msg("A transfer hook extension constraint was violated")]
  168. ConstraintMintTransferHookExtension,
  169. /// 2038 - A transfer hook extension authority constraint was violated
  170. #[msg("A transfer hook extension authority constraint was violated")]
  171. ConstraintMintTransferHookExtensionAuthority,
  172. /// 2039 - A transfer hook extension transfer hook program id constraint was violated
  173. #[msg("A transfer hook extension transfer hook program id constraint was violated")]
  174. ConstraintMintTransferHookExtensionProgramId,
  175. // Require
  176. /// 2500 - A require expression was violated
  177. #[msg("A require expression was violated")]
  178. RequireViolated = 2500,
  179. /// 2501 - A require_eq expression was violated
  180. #[msg("A require_eq expression was violated")]
  181. RequireEqViolated,
  182. /// 2502 - A require_keys_eq expression was violated
  183. #[msg("A require_keys_eq expression was violated")]
  184. RequireKeysEqViolated,
  185. /// 2503 - A require_neq expression was violated
  186. #[msg("A require_neq expression was violated")]
  187. RequireNeqViolated,
  188. /// 2504 - A require_keys_neq expression was violated
  189. #[msg("A require_keys_neq expression was violated")]
  190. RequireKeysNeqViolated,
  191. /// 2505 - A require_gt expression was violated
  192. #[msg("A require_gt expression was violated")]
  193. RequireGtViolated,
  194. /// 2506 - A require_gte expression was violated
  195. #[msg("A require_gte expression was violated")]
  196. RequireGteViolated,
  197. // Accounts.
  198. /// 3000 - The account discriminator was already set on this account
  199. #[msg("The account discriminator was already set on this account")]
  200. AccountDiscriminatorAlreadySet = 3000,
  201. /// 3001 - No discriminator was found on the account
  202. #[msg("No discriminator was found on the account")]
  203. AccountDiscriminatorNotFound,
  204. /// 3002 - Account discriminator did not match what was expected
  205. #[msg("Account discriminator did not match what was expected")]
  206. AccountDiscriminatorMismatch,
  207. /// 3003 - Failed to deserialize the account
  208. #[msg("Failed to deserialize the account")]
  209. AccountDidNotDeserialize,
  210. /// 3004 - Failed to serialize the account
  211. #[msg("Failed to serialize the account")]
  212. AccountDidNotSerialize,
  213. /// 3005 - Not enough account keys given to the instruction
  214. #[msg("Not enough account keys given to the instruction")]
  215. AccountNotEnoughKeys,
  216. /// 3006 - The given account is not mutable
  217. #[msg("The given account is not mutable")]
  218. AccountNotMutable,
  219. /// 3007 - The given account is owned by a different program than expected
  220. #[msg("The given account is owned by a different program than expected")]
  221. AccountOwnedByWrongProgram,
  222. /// 3008 - Program ID was not as expected
  223. #[msg("Program ID was not as expected")]
  224. InvalidProgramId,
  225. /// 3009 - Program account is not executable
  226. #[msg("Program account is not executable")]
  227. InvalidProgramExecutable,
  228. /// 3010 - The given account did not sign
  229. #[msg("The given account did not sign")]
  230. AccountNotSigner,
  231. /// 3011 - The given account is not owned by the system program
  232. #[msg("The given account is not owned by the system program")]
  233. AccountNotSystemOwned,
  234. /// 3012 - The program expected this account to be already initialized
  235. #[msg("The program expected this account to be already initialized")]
  236. AccountNotInitialized,
  237. /// 3013 - The given account is not a program data account
  238. #[msg("The given account is not a program data account")]
  239. AccountNotProgramData,
  240. /// 3014 - The given account is not the associated token account
  241. #[msg("The given account is not the associated token account")]
  242. AccountNotAssociatedTokenAccount,
  243. /// 3015 - The given public key does not match the required sysvar
  244. #[msg("The given public key does not match the required sysvar")]
  245. AccountSysvarMismatch,
  246. /// 3016 - The account reallocation exceeds the MAX_PERMITTED_DATA_INCREASE limit
  247. #[msg("The account reallocation exceeds the MAX_PERMITTED_DATA_INCREASE limit")]
  248. AccountReallocExceedsLimit,
  249. /// 3017 - The account was duplicated for more than one reallocation
  250. #[msg("The account was duplicated for more than one reallocation")]
  251. AccountDuplicateReallocs,
  252. // Miscellaneous
  253. /// 4100 - The declared program id does not match actual program id
  254. #[msg("The declared program id does not match the actual program id")]
  255. DeclaredProgramIdMismatch = 4100,
  256. /// 4101 - You cannot/should not initialize the payer account as a program account
  257. #[msg("You cannot/should not initialize the payer account as a program account")]
  258. TryingToInitPayerAsProgramAccount = 4101,
  259. /// 4102 - Invalid numeric conversion error
  260. #[msg("Error during numeric conversion")]
  261. InvalidNumericConversion = 4102,
  262. // Deprecated
  263. /// 5000 - The API being used is deprecated and should no longer be used
  264. #[msg("The API being used is deprecated and should no longer be used")]
  265. Deprecated = 5000,
  266. }
  267. #[derive(Debug, PartialEq, Eq)]
  268. pub enum Error {
  269. AnchorError(Box<AnchorError>),
  270. ProgramError(Box<ProgramErrorWithOrigin>),
  271. }
  272. impl std::error::Error for Error {}
  273. impl Display for Error {
  274. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  275. match self {
  276. Error::AnchorError(ae) => Display::fmt(&ae, f),
  277. Error::ProgramError(pe) => Display::fmt(&pe, f),
  278. }
  279. }
  280. }
  281. impl From<AnchorError> for Error {
  282. fn from(ae: AnchorError) -> Self {
  283. Self::AnchorError(Box::new(ae))
  284. }
  285. }
  286. impl From<ProgramError> for Error {
  287. fn from(program_error: ProgramError) -> Self {
  288. Self::ProgramError(Box::new(program_error.into()))
  289. }
  290. }
  291. impl From<BorshIoError> for Error {
  292. fn from(error: BorshIoError) -> Self {
  293. Error::ProgramError(Box::new(ProgramError::from(error).into()))
  294. }
  295. }
  296. impl From<ProgramErrorWithOrigin> for Error {
  297. fn from(pe: ProgramErrorWithOrigin) -> Self {
  298. Self::ProgramError(Box::new(pe))
  299. }
  300. }
  301. impl From<TryFromIntError> for Error {
  302. fn from(e: TryFromIntError) -> Self {
  303. Self::AnchorError(Box::new(AnchorError {
  304. error_name: ErrorCode::InvalidNumericConversion.name(),
  305. error_code_number: ErrorCode::InvalidNumericConversion.into(),
  306. error_msg: format!("{}", e),
  307. error_origin: None,
  308. compared_values: None,
  309. }))
  310. }
  311. }
  312. impl Error {
  313. pub fn log(&self) {
  314. match self {
  315. Error::ProgramError(program_error) => program_error.log(),
  316. Error::AnchorError(anchor_error) => anchor_error.log(),
  317. }
  318. }
  319. pub fn with_account_name(mut self, account_name: impl ToString) -> Self {
  320. match &mut self {
  321. Error::AnchorError(ae) => {
  322. ae.error_origin = Some(ErrorOrigin::AccountName(account_name.to_string()));
  323. }
  324. Error::ProgramError(pe) => {
  325. pe.error_origin = Some(ErrorOrigin::AccountName(account_name.to_string()));
  326. }
  327. };
  328. self
  329. }
  330. pub fn with_source(mut self, source: Source) -> Self {
  331. match &mut self {
  332. Error::AnchorError(ae) => {
  333. ae.error_origin = Some(ErrorOrigin::Source(source));
  334. }
  335. Error::ProgramError(pe) => {
  336. pe.error_origin = Some(ErrorOrigin::Source(source));
  337. }
  338. };
  339. self
  340. }
  341. pub fn with_pubkeys(mut self, pubkeys: (Pubkey, Pubkey)) -> Self {
  342. let pubkeys = Some(ComparedValues::Pubkeys((pubkeys.0, pubkeys.1)));
  343. match &mut self {
  344. Error::AnchorError(ae) => ae.compared_values = pubkeys,
  345. Error::ProgramError(pe) => pe.compared_values = pubkeys,
  346. };
  347. self
  348. }
  349. pub fn with_values(mut self, values: (impl ToString, impl ToString)) -> Self {
  350. match &mut self {
  351. Error::AnchorError(ae) => {
  352. ae.compared_values = Some(ComparedValues::Values((
  353. values.0.to_string(),
  354. values.1.to_string(),
  355. )))
  356. }
  357. Error::ProgramError(pe) => {
  358. pe.compared_values = Some(ComparedValues::Values((
  359. values.0.to_string(),
  360. values.1.to_string(),
  361. )))
  362. }
  363. };
  364. self
  365. }
  366. }
  367. #[derive(Debug)]
  368. pub struct ProgramErrorWithOrigin {
  369. pub program_error: ProgramError,
  370. pub error_origin: Option<ErrorOrigin>,
  371. pub compared_values: Option<ComparedValues>,
  372. }
  373. // Two ProgramErrors are equal when they have the same error code
  374. impl PartialEq for ProgramErrorWithOrigin {
  375. fn eq(&self, other: &Self) -> bool {
  376. self.program_error == other.program_error
  377. }
  378. }
  379. impl Eq for ProgramErrorWithOrigin {}
  380. impl Display for ProgramErrorWithOrigin {
  381. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  382. Display::fmt(&self.program_error, f)
  383. }
  384. }
  385. impl ProgramErrorWithOrigin {
  386. pub fn log(&self) {
  387. match &self.error_origin {
  388. None => {
  389. anchor_lang::solana_program::msg!(
  390. "ProgramError occurred. Error Code: {:?}. Error Number: {}. Error Message: {}.",
  391. self.program_error,
  392. u64::from(self.program_error.clone()),
  393. self.program_error
  394. );
  395. }
  396. Some(ErrorOrigin::Source(source)) => {
  397. anchor_lang::solana_program::msg!(
  398. "ProgramError thrown in {}:{}. Error Code: {:?}. Error Number: {}. Error Message: {}.",
  399. source.filename,
  400. source.line,
  401. self.program_error,
  402. u64::from(self.program_error.clone()),
  403. self.program_error
  404. );
  405. }
  406. Some(ErrorOrigin::AccountName(account_name)) => {
  407. // using sol_log because msg! wrongly interprets 5 inputs as u64
  408. anchor_lang::solana_program::log::sol_log(&format!(
  409. "ProgramError caused by account: {}. Error Code: {:?}. Error Number: {}. Error Message: {}.",
  410. account_name,
  411. self.program_error,
  412. u64::from(self.program_error.clone()),
  413. self.program_error
  414. ));
  415. }
  416. }
  417. match &self.compared_values {
  418. Some(ComparedValues::Pubkeys((left, right))) => {
  419. anchor_lang::solana_program::msg!("Left:");
  420. left.log();
  421. anchor_lang::solana_program::msg!("Right:");
  422. right.log();
  423. }
  424. Some(ComparedValues::Values((left, right))) => {
  425. anchor_lang::solana_program::msg!("Left: {}", left);
  426. anchor_lang::solana_program::msg!("Right: {}", right);
  427. }
  428. None => (),
  429. }
  430. }
  431. pub fn with_source(mut self, source: Source) -> Self {
  432. self.error_origin = Some(ErrorOrigin::Source(source));
  433. self
  434. }
  435. pub fn with_account_name(mut self, account_name: impl ToString) -> Self {
  436. self.error_origin = Some(ErrorOrigin::AccountName(account_name.to_string()));
  437. self
  438. }
  439. }
  440. impl From<ProgramError> for ProgramErrorWithOrigin {
  441. fn from(program_error: ProgramError) -> Self {
  442. Self {
  443. program_error,
  444. error_origin: None,
  445. compared_values: None,
  446. }
  447. }
  448. }
  449. #[derive(Debug)]
  450. pub enum ComparedValues {
  451. Values((String, String)),
  452. Pubkeys((Pubkey, Pubkey)),
  453. }
  454. #[derive(Debug)]
  455. pub enum ErrorOrigin {
  456. Source(Source),
  457. AccountName(String),
  458. }
  459. #[derive(Debug)]
  460. pub struct AnchorError {
  461. pub error_name: String,
  462. pub error_code_number: u32,
  463. pub error_msg: String,
  464. pub error_origin: Option<ErrorOrigin>,
  465. pub compared_values: Option<ComparedValues>,
  466. }
  467. impl AnchorError {
  468. pub fn log(&self) {
  469. match &self.error_origin {
  470. None => {
  471. anchor_lang::solana_program::log::sol_log(&format!(
  472. "AnchorError occurred. Error Code: {}. Error Number: {}. Error Message: {}.",
  473. self.error_name, self.error_code_number, self.error_msg
  474. ));
  475. }
  476. Some(ErrorOrigin::Source(source)) => {
  477. anchor_lang::solana_program::msg!(
  478. "AnchorError thrown in {}:{}. Error Code: {}. Error Number: {}. Error Message: {}.",
  479. source.filename,
  480. source.line,
  481. self.error_name,
  482. self.error_code_number,
  483. self.error_msg
  484. );
  485. }
  486. Some(ErrorOrigin::AccountName(account_name)) => {
  487. anchor_lang::solana_program::log::sol_log(&format!(
  488. "AnchorError caused by account: {}. Error Code: {}. Error Number: {}. Error Message: {}.",
  489. account_name,
  490. self.error_name,
  491. self.error_code_number,
  492. self.error_msg
  493. ));
  494. }
  495. }
  496. match &self.compared_values {
  497. Some(ComparedValues::Pubkeys((left, right))) => {
  498. anchor_lang::solana_program::msg!("Left:");
  499. left.log();
  500. anchor_lang::solana_program::msg!("Right:");
  501. right.log();
  502. }
  503. Some(ComparedValues::Values((left, right))) => {
  504. anchor_lang::solana_program::msg!("Left: {}", left);
  505. anchor_lang::solana_program::msg!("Right: {}", right);
  506. }
  507. None => (),
  508. }
  509. }
  510. pub fn with_source(mut self, source: Source) -> Self {
  511. self.error_origin = Some(ErrorOrigin::Source(source));
  512. self
  513. }
  514. pub fn with_account_name(mut self, account_name: impl ToString) -> Self {
  515. self.error_origin = Some(ErrorOrigin::AccountName(account_name.to_string()));
  516. self
  517. }
  518. }
  519. impl Display for AnchorError {
  520. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  521. Debug::fmt(&self, f)
  522. }
  523. }
  524. /// Two `AnchorError`s are equal when they have the same error code
  525. impl PartialEq for AnchorError {
  526. fn eq(&self, other: &Self) -> bool {
  527. self.error_code_number == other.error_code_number
  528. }
  529. }
  530. impl Eq for AnchorError {}
  531. impl std::convert::From<Error> for anchor_lang::solana_program::program_error::ProgramError {
  532. fn from(e: Error) -> anchor_lang::solana_program::program_error::ProgramError {
  533. match e {
  534. Error::AnchorError(error) => {
  535. anchor_lang::solana_program::program_error::ProgramError::Custom(
  536. error.error_code_number,
  537. )
  538. }
  539. Error::ProgramError(program_error) => program_error.program_error,
  540. }
  541. }
  542. }
  543. #[derive(Debug)]
  544. pub struct Source {
  545. pub filename: &'static str,
  546. pub line: u32,
  547. }