Skip to content

Counter proposal : type safe try/catch #43

@y-nk

Description

@y-nk

The proposal seems copying Golang famous value, _ := blah() but I think we can do better in error handling if we copied dart/java instead.

Considering the 1st example:

async function getData() {
  const [requestError, response] ?= await fetch(
    "https://api.example.com/data"
  )

  if (requestError) {
    handleRequestError(requestError)
    return
  }

  const [parseError, json] ?= await response.json()

  if (parseError) {
    handleParseError(parseError)
    return
  }

  const [validationError, data] ?= validationSchema.parse(json)

  if (validationError) {
    handleValidationError(validationError)
    return
  }

  return data
}

I would rather leverage a new on XXX catch (err) instead which would look like this:

async function getData() {
  try {
    cons res = await fetch("https://api.example.com/data")

    return validationSchema.parse(
      await res.json()
    )
  }
  on RequestError catch (err) {
    handleRequestError(err)
  }
  on ParseError catch (err) {
    handleValidationError(err)
  }
  on ValidationError catch (err) {
    handleValidationError(err)
  }
  catch (err) {
    handleUnknownError(err)
  }
}

Advantages over your proposal:

  1. we can read happy path without "if error" interrupting every 2 lines
  2. the example provided does not provide type checking on the errors so you will end up with a if/else or a big switch case if you missed one or if the errors are not granular in the "below" layer (for example, try adding network error handling in fetch call and we'll see)
  3. it encourages people to throw (typed) Error instances (rather than returning strings and whatnot)
  4. try catch can provide an escape hatch like a global catch with the final catch, but this not really different from the proposal
  5. errors can still bubble up in the stack which is very powerful

EDIT: this addresses your concerns about nested try/catch

EDIT2: would consider also rethrow as a syntaxic sugar of throw err, that'd be nice but it's not really inside the proposal

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions