Skip to content

Error Handling for Mnemonic Functions

← Back to Mnemonic Utilities

This example demonstrates how to properly handle errors when working with mnemonic functions, including invalid words, bad checksums, and wrong seed lengths. Key concepts:

  • NOT_IN_WORDS_LIST_ERROR_MSG: Thrown when a mnemonic contains an invalid word
  • FAIL_TO_DECODE_MNEMONIC_ERROR_MSG: Thrown when checksum validation fails
  • RangeError: Thrown when seed length is not 32 bytes
  • No LocalNet required

From the repository root:

Terminal window
cd examples
npm run example algo25/05-error-handling.ts

View source on GitHub

05-error-handling.ts
/**
* Example: Error Handling for Mnemonic Functions
*
* This example demonstrates how to properly handle errors when working with
* mnemonic functions, including invalid words, bad checksums, and wrong seed lengths.
*
* Key concepts:
* - NOT_IN_WORDS_LIST_ERROR_MSG: Thrown when a mnemonic contains an invalid word
* - FAIL_TO_DECODE_MNEMONIC_ERROR_MSG: Thrown when checksum validation fails
* - RangeError: Thrown when seed length is not 32 bytes
*
* Prerequisites:
* - No LocalNet required
*/
import {
FAIL_TO_DECODE_MNEMONIC_ERROR_MSG,
mnemonicFromSeed,
NOT_IN_WORDS_LIST_ERROR_MSG,
seedFromMnemonic,
} from '@algorandfoundation/algokit-utils/algo25'
import { printError, printHeader, printInfo, printStep, printSuccess } from '../shared/utils.js'
function main() {
printHeader('Error Handling for Mnemonic Functions')
// Step 1: Display the error constants
printStep(1, 'Error Constants and Their Values')
printInfo('The algo25 package exports two error message constants:')
printInfo('')
printInfo(' NOT_IN_WORDS_LIST_ERROR_MSG:')
printInfo(` Value: "${NOT_IN_WORDS_LIST_ERROR_MSG}"`)
printInfo(' When: A word in the mnemonic is not in the BIP39 wordlist')
printInfo('')
printInfo(' FAIL_TO_DECODE_MNEMONIC_ERROR_MSG:')
printInfo(` Value: "${FAIL_TO_DECODE_MNEMONIC_ERROR_MSG}"`)
printInfo(' When: Checksum validation fails or mnemonic structure is invalid')
printInfo('')
printInfo('Additionally, mnemonicFromSeed() throws RangeError for wrong seed length.')
// Step 2: Demonstrate NOT_IN_WORDS_LIST_ERROR_MSG error
printStep(2, 'Error: Invalid Word Not in Wordlist')
// Create a mnemonic with an invalid word
const invalidWordMnemonic =
'invalidword abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon'
printInfo('Attempting to decode a mnemonic with an invalid word...')
printInfo(` First word: "invalidword" (not in BIP39 wordlist)`)
printInfo('')
try {
seedFromMnemonic(invalidWordMnemonic)
printError('Unexpectedly succeeded - this should have thrown an error!')
} catch (error) {
const errorMessage = (error as Error).message
printInfo(`Caught error: "${errorMessage}"`)
printInfo('')
// Demonstrate programmatic error checking
if (errorMessage === NOT_IN_WORDS_LIST_ERROR_MSG) {
printSuccess('Error message matches NOT_IN_WORDS_LIST_ERROR_MSG constant')
printInfo('')
printInfo('Programmatic handling pattern:')
printInfo(' if (error.message === NOT_IN_WORDS_LIST_ERROR_MSG) {')
printInfo(' // Handle invalid word error')
printInfo(' // e.g., prompt user to check their mnemonic spelling')
printInfo(' }')
}
}
// Step 3: Demonstrate FAIL_TO_DECODE_MNEMONIC_ERROR_MSG error
printStep(3, 'Error: Invalid Checksum')
// Create a mnemonic with valid words but invalid checksum
// Using all "abandon" words creates a valid structure but wrong checksum
const invalidChecksumMnemonic =
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon wrong'
printInfo('Attempting to decode a mnemonic with valid words but invalid checksum...')
printInfo(' All 24 data words: "abandon" (valid BIP39 word)')
printInfo(' Checksum word: "wrong" (valid word, but incorrect checksum)')
printInfo('')
try {
seedFromMnemonic(invalidChecksumMnemonic)
printError('Unexpectedly succeeded - this should have thrown an error!')
} catch (error) {
const errorMessage = (error as Error).message
printInfo(`Caught error: "${errorMessage}"`)
printInfo('')
// Demonstrate programmatic error checking
if (errorMessage === FAIL_TO_DECODE_MNEMONIC_ERROR_MSG) {
printSuccess('Error message matches FAIL_TO_DECODE_MNEMONIC_ERROR_MSG constant')
printInfo('')
printInfo('Programmatic handling pattern:')
printInfo(' if (error.message === FAIL_TO_DECODE_MNEMONIC_ERROR_MSG) {')
printInfo(' // Handle checksum validation error')
printInfo(' // e.g., prompt user to verify their mnemonic phrase')
printInfo(' }')
}
}
// Step 4: Demonstrate RangeError for wrong seed length
printStep(4, 'Error: Wrong Seed Length')
// Create seeds with wrong lengths
const shortSeed = new Uint8Array(16) // Too short (16 bytes instead of 32)
const longSeed = new Uint8Array(64) // Too long (64 bytes instead of 32)
printInfo('mnemonicFromSeed() requires exactly 32 bytes.')
printInfo('Attempting with incorrect seed lengths...')
printInfo('')
// Test with short seed
printInfo('Test 1: 16-byte seed (too short)')
try {
mnemonicFromSeed(shortSeed)
printError('Unexpectedly succeeded - this should have thrown an error!')
} catch (error) {
const errorMessage = (error as Error).message
const isRangeError = error instanceof RangeError
printInfo(` Caught ${isRangeError ? 'RangeError' : 'Error'}: "${errorMessage}"`)
if (isRangeError) {
printSuccess(' Correctly threw RangeError for wrong seed length')
}
}
printInfo('')
// Test with long seed
printInfo('Test 2: 64-byte seed (too long)')
try {
mnemonicFromSeed(longSeed)
printError('Unexpectedly succeeded - this should have thrown an error!')
} catch (error) {
const errorMessage = (error as Error).message
const isRangeError = error instanceof RangeError
printInfo(` Caught ${isRangeError ? 'RangeError' : 'Error'}: "${errorMessage}"`)
if (isRangeError) {
printSuccess(' Correctly threw RangeError for wrong seed length')
}
}
printInfo('')
printInfo('Programmatic handling pattern:')
printInfo(' if (error instanceof RangeError) {')
printInfo(' // Handle wrong seed length error')
printInfo(' // e.g., validate input data before calling mnemonicFromSeed()')
printInfo(' }')
// Step 5: Comprehensive try/catch pattern
printStep(5, 'Comprehensive Error Handling Pattern')
printInfo('Here is a complete try/catch pattern for mnemonic functions:')
printInfo('')
printInfo(' try {')
printInfo(' const seed = seedFromMnemonic(userInput)')
printInfo(' // Success - use the seed')
printInfo(' } catch (error) {')
printInfo(' if (error instanceof Error) {')
printInfo(' if (error.message === NOT_IN_WORDS_LIST_ERROR_MSG) {')
printInfo(' // One or more words are not in the BIP39 wordlist')
printInfo(' // Action: Check spelling, ensure words are lowercase')
printInfo(' } else if (error.message === FAIL_TO_DECODE_MNEMONIC_ERROR_MSG) {')
printInfo(' // Checksum validation failed')
printInfo(' // Action: Verify the complete mnemonic phrase')
printInfo(' } else if (error instanceof RangeError) {')
printInfo(' // Wrong seed length (for mnemonicFromSeed)')
printInfo(' // Action: Ensure seed is exactly 32 bytes')
printInfo(' } else {')
printInfo(' // Unexpected error')
printInfo(' // Action: Log and report')
printInfo(' }')
printInfo(' }')
printInfo(' }')
// Step 6: Demonstrate a successful operation for comparison
printStep(6, 'Successful Operation for Comparison')
const validSeed = new Uint8Array(32)
crypto.getRandomValues(validSeed)
printInfo('Creating a valid mnemonic from a 32-byte seed...')
try {
const validMnemonic = mnemonicFromSeed(validSeed)
const words = validMnemonic.split(' ')
printSuccess(`Generated valid mnemonic with ${words.length} words`)
printInfo(` First 3 words: "${words.slice(0, 3).join(' ')}..."`)
// Round-trip to verify
const recoveredSeed = seedFromMnemonic(validMnemonic)
printSuccess('Successfully recovered seed from mnemonic (no errors)')
printInfo(` Recovered seed length: ${recoveredSeed.length} bytes`)
} catch (error) {
printError(`Unexpected error: ${(error as Error).message}`)
}
// Step 7: Summary
printStep(7, 'Summary')
printInfo('Error handling best practices for mnemonic functions:')
printInfo('')
printInfo(' 1. Import error constants for programmatic checking:')
printInfo(' import { FAIL_TO_DECODE_MNEMONIC_ERROR_MSG, NOT_IN_WORDS_LIST_ERROR_MSG }')
printInfo('')
printInfo(' 2. Three types of errors to handle:')
printInfo(' - NOT_IN_WORDS_LIST_ERROR_MSG: Invalid word in mnemonic')
printInfo(' - FAIL_TO_DECODE_MNEMONIC_ERROR_MSG: Checksum validation failed')
printInfo(' - RangeError: Seed is not exactly 32 bytes')
printInfo('')
printInfo(' 3. Always use try/catch when processing user-provided mnemonics')
printInfo('')
printInfo(' 4. Compare error.message against constants for specific handling')
printInfo('')
printInfo(' 5. Use instanceof RangeError for seed length errors')
printSuccess('Error Handling example completed successfully!')
}
main()