error

Version, currently 0.1.02 versions

github.com/j8r/error.cr

Efficient errors without raising - no expensive stack unwinding

8 stars
0 dependents
License: ISC

Nothing has been indexed for 0.1.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.

Installation

# Add this to your shard.yml
dependencies:
  error:
    github: j8r/error.cr
    version: ~> 0.1.0

Then run:

shards install

shard.yml

No shard.yml has been indexed for 0.1.0. You can read it on the repository.

Dependencies

Unknown: the shard.yml for this version has not been read yet.

README

This README is the one indexed from the repository at its latest ref, not from the tag for this version.

# Crystal Error

[![Build Status](https://cloud.drone.io/api/badges/j8r/error.cr/status.svg)](https://cloud.drone.io/j8r/error.cr)
[![ISC](https://img.shields.io/badge/License-ISC-blue.svg?style=flat-square)](https://en.wikipedia.org/wiki/ISC_license)

An efficient way to handle errors without using `raise` - no expensive stack unwinding.

## Advantages

Over "classic" `Exception` errors, this approach provides:

- Shorter traces without stdlib related calls
- More useful output with the object and method called
- More performant than unwinding the stack (what `raise` does)

The main disadvantage is the slight verbosity added, having a new type `Error` type to handle.
On the other side `begin/rescue` aren't needed

## Installation

Add the dependency to your `shard.yml`:

```yaml
dependencies:
  error:
    github: j8r/error.cr
```

## Usage

### Simple error

```crystal
require "error"

def it_throws
  Error.throw "Oops!"
end
p it_throws
```
result:
```
Oops! (Error)
   from myapp.cr:4 in 'it_throws'
```

### Handling errors

```crystal
require "error"

struct Obj
  def action : String | Error
    Error.throw("Shouldn't be true") || "normal"
  end
end

def main_program : String | Error
  case result = Obj.new.action
  # Throw the error on the top.
  # Optionaly, the message can be modified and a parent error specified.
  when Error then Error.throw "Action not successful: #{result}", result
  else            "operation successful: " + result
  end
end

p main_program
```
result:
```
Action not successful: Shouldn't be true (Error)
   from myapp.cr:5 in 'Obj#action'
   from myapp.cr:13 in 'main_program'
```

### Custom errors

```crystal
class CustomError < Error
  @message = "This is a custom error message"
end

def action
  CustomError.throw
end

p action
```
result:
```
This is a custom error message (CustomError)
   from app.cr:6 in 'action'
```

## FAQ

### I can't use this in my main program.

This libary can only be used inside methods, because the `Error.throw` macro expands to a `return Error`.

### This doesn't work in the `initialize` of my class!

A class initializer can't return an union, only an instance of the class.

You can create a `self.new` method that returns the union of the class and `Error`.

## License

Copyright (c) 2018-2019 Julien Reichardt - ISC License