Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

eff/try.fz


# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation.  If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
#  Tokiwa Software GmbH, Germany
#
#  Source code of Fuzion standard library feature try
#
#  Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------

# try -- try to run code requiring fallible effect and handle failure
#
# This feature allows Java-like try-catch syntax for fallible
#
#     res := try ERROR_TYPE FALLIBLE_TYPE RESULT_TYPE ()->
#               code
#            .catch s->
#               handle failure condition `s`
#
# or even
#
#     res := try ERROR_TYPE FALLIBLE_TYPE RESULT_TYPE code || (s->handle post condition failure `s`)
#
public try(ERROR type, F type : fallible ERROR, T type, code_try ()->T) is

  # a local mutate used for storing an error
  # when throwing an exception
  #
  lm : mutate is

  # define code to execute in case of fault and run code
  #
  public catch(code_catch ERROR->T) T =>
    lm ! ()->
      catch0 code_catch


  # catch that uses an already instated local mutate
  #
  # this is necessary e.g. for `or_try` to avoid
  # an `invalid mutate` error.
  #
  catch0(code_catch ERROR->T) T ! lm =>
    m := lm.env.new (option ERROR nil)
    v := F.new e->
              m <- e
              F.abort
    F.instate T v code_try (_ -> code_catch m.get.or_panic)


  # on failure try if code `alt` succeeds
  #
  # usage example:
  #
  #     fuzion.runtime.contract_fault
  #       .try ()->(envir.args.nth 3).or_panic.trim.parse_i32.or_panic
  #       .or_try _->envir.vars["DEBUG_LEVEL"].or_panic.trim.parse_i32.or_panic
  #       .catch  _->4
  #
  public or_try(alt ERROR->T) try ERROR F T =>
    try ERROR F _ ()->
      catch0 alt



  # infix alias for catch
  #
  infix || (code_catch ERROR->T) => catch code_catch

last changed: 2026-04-21