E4122

E4122#

Invalid raise operation. Can only be used inside a function with error types in its signature.

There are 3 raise operations in MoonBit, and they must be used inside a function with error types in its signature or a try block.

  • Use the raise keyword to raise an error directly.

  • Re-raise an error by simply applying a function that raises an error.

  • Explicitly handle the error using the try ... catch! ... block. The catch! means re-raise all the errors that are not handled in the catch block.

Warning

The catch! syntax is deprecated. Use catch {e => raise e} to reraise explicitly.

Erroneous example#

  • Raise the error directly:

    ///|
    priv suberror ArithmeticError {
      DivisionByZero
    }
    
    ///|
    pub fn checked_div(a : Double, b : Double) -> Double {
      if b == 0.0 {
        raise DivisionByZero // Error: raise can only be used inside ...
      }
      return a / b
    }
    
  • Re-raise the error:

    ///|
    pub fn rethrow() -> Unit {
      // Error: Function with error can only be used 
      // inside a function with error types in its signature
      fail("throwing")
    }
    
  • Catch all errors using catch!:

    ///|
    pub fn catch_all() -> Double {
      // Error: catch! will rethrow unhandled error, and can only be used inside ...
      fail("Failed") catch! {
    
      }
    }
    

Suggestion#

You can either modify the surrounding function to have error types in its signature:

///|
suberror ArithmeticError {
  DivisionByZero
}

///|
pub fn checked_div(a : Double, b : Double) -> Double raise ArithmeticError {
  ...
}

///|
pub fn rethrow() -> Unit raise {
  ...
}

///|
pub fn catch_all() -> Double raise {
  ...
}

Or use the try ... catch ... block to handle the error:

///|
pub fn checked_div_noraise(a : Double, b : Double) -> Double noraise {
  try {
    if b == 0.0 {
      raise DivisionByZero
    }
    return a / b
  } catch {
    DivisionByZero => @double.not_a_number
  }
}