Преглед на файлове

lang: Implement `TryFromIntError` for `Error` (#2950)

CanardMandarin преди 1 година
родител
ревизия
b7dff46267
променени са 5 файла, в които са добавени 43 реда и са изтрити 0 реда
  1. 1 0
      CHANGELOG.md
  2. 16 0
      lang/src/error.rs
  3. 4 0
      tests/errors/programs/errors/src/lib.rs
  4. 17 0
      tests/errors/tests/errors.ts
  5. 5 0
      ts/packages/anchor/src/error.ts

+ 1 - 0
CHANGELOG.md

@@ -17,6 +17,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 - avm: Optimize `avm list` when GitHub API rate limits are reached ([#2962](https://github.com/coral-xyz/anchor/pull/2962))
 - idl, ts: Add accounts resolution for associated token accounts ([#2927](https://github.com/coral-xyz/anchor/pull/2927)).
 - cli: Add `--no-install` option to the `init` command ([#2945](https://github.com/coral-xyz/anchor/pull/2945)).
+- lang: Implement `TryFromIntError` for `Error` to be able to propagate integer conversion errors ([#2950](https://github.com/coral-xyz/anchor/pull/2950)).
 
 ### Fixes
 

+ 16 - 0
lang/src/error.rs

@@ -2,6 +2,7 @@ use anchor_lang::error_code;
 use borsh::maybestd::io::Error as BorshIoError;
 use solana_program::{program_error::ProgramError, pubkey::Pubkey};
 use std::fmt::{Debug, Display};
+use std::num::TryFromIntError;
 
 /// The starting point for user defined error codes.
 pub const ERROR_CODE_OFFSET: u32 = 6000;
@@ -263,6 +264,9 @@ pub enum ErrorCode {
     /// 4101 - You cannot/should not initialize the payer account as a program account
     #[msg("You cannot/should not initialize the payer account as a program account")]
     TryingToInitPayerAsProgramAccount = 4101,
+    /// 4102 - Invalid numeric conversion error
+    #[msg("Error during numeric conversion")]
+    InvalidNumericConversion = 4102,
 
     // Deprecated
     /// 5000 - The API being used is deprecated and should no longer be used
@@ -310,6 +314,18 @@ impl From<ProgramErrorWithOrigin> for Error {
     }
 }
 
+impl From<TryFromIntError> for Error {
+    fn from(e: TryFromIntError) -> Self {
+        Self::AnchorError(Box::new(AnchorError {
+            error_name: ErrorCode::InvalidNumericConversion.name(),
+            error_code_number: ErrorCode::InvalidNumericConversion.into(),
+            error_msg: format!("{}", e),
+            error_origin: None,
+            compared_values: None,
+        }))
+    }
+}
+
 impl Error {
     pub fn log(&self) {
         match self {

+ 4 - 0
tests/errors/programs/errors/src/lib.rs

@@ -131,6 +131,10 @@ mod errors {
         require_gte!(5, 10);
         Ok(())
     }
+
+    pub fn try_into_integer(_ctx: Context<Hello>) -> Result<i64> {
+        Ok(u64::MAX.try_into()?)
+    }
 }
 
 #[derive(Accounts)]

+ 17 - 0
tests/errors/tests/errors.ts

@@ -604,4 +604,21 @@ describe("errors", () => {
       "Program log: Right: 10",
     ]);
   });
+
+  it("Emits a InvalidNumericConversion error via try_into", async () => {
+    await withLogTest(async () => {
+      try {
+        const tx = await program.methods.tryIntoInteger().rpc();
+        assert.fail(
+          "Unexpected success in creating a transaction that should have failed with `InvalidNumericConversion` error"
+        );
+      } catch (_err) {
+        assert.isTrue(_err instanceof AnchorError);
+        const err: AnchorError = _err;
+        assert.strictEqual(err.error.errorCode.number, 4102);
+      }
+    }, [
+      "Program log: AnchorError occurred. Error Code: InvalidNumericConversion. Error Number: 4102. Error Message: out of range integral type conversion attempted.",
+    ]);
+  });
 });

+ 5 - 0
ts/packages/anchor/src/error.ts

@@ -394,6 +394,7 @@ export const LangErrorCode = {
   // Miscellaneous
   DeclaredProgramIdMismatch: 4100,
   TryingToInitPayerAsProgramAccount: 4101,
+  InvalidNumericConversion: 4102,
 
   // Used for APIs that shouldn't be used anymore.
   Deprecated: 5000,
@@ -638,6 +639,10 @@ export const LangErrorMessage = new Map([
     LangErrorCode.TryingToInitPayerAsProgramAccount,
     "You cannot/should not initialize the payer account as a program account",
   ],
+  [
+    LangErrorCode.InvalidNumericConversion,
+    "The program could not perform the numeric conversion, out of range integral type conversion attempted",
+  ],
 
   // Deprecated
   [