Errors in external calls may be handled by the Flint programmer manually, using the call (default mode) together with a do ... catch block. As a consequence, a call should always occur within a do ... catch block (in the same function). Additionally, a call! should not occur within a do ... catch block, since it may be misleading as the do ... catch doesn't actually handle errors of a call!. if let ... = call? { ... } is allowed both inside and outside do ... catch blocks, since it handles its own errors unambiguously.
// valid code
if let x: Int = call? ext.someReturningFunc() { ... } else { ... }
do {
call ext.someFunc()
// call? can occur anywhere
if let x: Int = call? ext.someReturningFunc() { ... } else { ... }
} catch is ExternalCallError { ... }
call! ext.someFunc() // call! can occur only outside of do ... catch
// invalid code:
do {
call! ext.someFunc() // forced mode cannot occur inside of do ... catch
} catch is ExternalCallError { ... }
call ext.someFunc() // default mode cannot occur outside of do ... catch
Keep in mind that do ... catch blocks may be nested.
Some of this is handled in #98
[ ] check that external call return values are never ignored
[ ] check that call! always occurs outside a do ... catch block
[ ] check that call? is only used in if let ... construct
(From #72)
Errors in external calls may be handled by the Flint programmer manually, using the
call
(default mode) together with ado ... catch
block. As a consequence, acall
should always occur within ado ... catch
block (in the same function). Additionally, acall!
should not occur within ado ... catch
block, since it may be misleading as thedo ... catch
doesn't actually handle errors of acall!
.if let ... = call? { ... }
is allowed both inside and outsidedo ... catch
blocks, since it handles its own errors unambiguously.Keep in mind that
do ... catch
blocks may be nested.Some of this is handled in #98
call!
always occurs outside ado ... catch
blockcall?
is only used inif let ...
construct