0.0.20 • Published 1 year ago

good-flow v0.0.20

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Overview

GoodFlow improves how you do errors in Javascript:

  • Emit and handle errors in a flat, Go-like way, avoiding nested try-catch blocks and use of mutable let variables.
  • Nest errors with inner errors to attach informative context.
  • Print errors to console beautifully.
  • Serialize errors to make it a DTO (e.g. to make it JSON-serializable).
  • Enable flat try-catch logic.

Usage Overview

import { createGFError, GFResult } from 'good-flow'

const task = (path: string): GFResult<string> => {
  try {
    // Emit successful result
    return [fs.readFileSync(path, { encoding: 'utf8' })]
  }
  catch (e: any) {
    // Emit unsuccessful result with error
    return [undefined, createGFError({
      msg: c => `Could not read file at ${c.cyan(path)}.`,
      inner: e,
    })]
  }
}

const [taskResult, err] = task()
// Handle error
if (err != null) {
  // Log error (simple)
  err.log()
  // Log error (explicit)
  console.log(err.toLogString())
  // Serialize and JSON-ify error
  myErrorDatabaseService.store(JSON.stringify(err.serialize()))
  exit(1)
}

exit(0)

Logging

Errors can be logged to a Node.js console. For example:

const err = createGFError('This is an error')
console.log(err.toLogString())
err.log() // Equivalent to above
err.log({ outlet: 'error' }) // // Equivalent to above but using console.error(...)

A preview of how errors log to console by default:

Logging Preview

Serialization

Errors can be serialized, converting them to a form that contains only serializable data (i.e. no functions, etc.). This enables them to be, for example, JSON-serializable and sent over a network as a DTO.

To create and serialize an error (e.g. server-side):

import { createGFError } from 'good-flow'

const err = createGFError('This is an error')
const serializedErr = err.serialize()
const errJson = JSON.stringify(serializedErr)

For client-side code, types for a serialized GFError are available seperately at good-flow/lib/serialized such that Node.js-only packages are not co-imported along (which would cause build/bundle issues for browsers). For example:

import { SerializedGFError } from 'good-flow/lib/serialized'

type MyApiResponse<TData> = { data: TData, err: SerializedGFError }

Try-Catching

Try-catch logic can be done in a flatter way that more easily integrates with GoodFlow via gfTry. For example:

import * as fs from 'fs'
import { gfTry } from 'good-flow'

const task = path => gfTry(
  // Try
  () => fs.readFileSync(path, { encoding: 'utf8' }),
  // Catch (can be take several forms)
  { msg: c => `Could not read configuration file at ${c.cyan(path)}.` },
)

const [result, error] = task('foo.txt')
/* error:
{  
  msg: Could not read configuration file at foo.txt
  inner: {
    name: 'ENOENT',
    message: 'File not found...',
    stack: ...,
    ...
  }
}
*/

Performance

The base concept of GoodFlow (function results as tuple of data and/or error) does not incur a significant performance impact over using a native try-catch block. Proof-of-concept. More rigorous performance tests and data are in the pipeline.

Development

See ./contributing/development.md


If you would like to support the development of GoodFlow, feel free to sponsor me on GitHub or buy me a coffee

0.0.20

1 year ago

0.0.19

1 year ago

0.0.18

1 year ago

0.0.17

1 year ago

0.0.16

1 year ago

0.0.15

1 year ago

0.0.14

1 year ago

0.0.14-beta1

1 year ago

0.0.14-beta0

1 year ago

0.0.13

1 year ago

0.0.12

1 year ago

0.0.11

1 year ago

0.0.10

1 year ago

0.0.9

1 year ago

0.0.8

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago