GithubHelp home page GithubHelp logo

neuronlabs / errors Goto Github PK

View Code? Open in Web Editor NEW
6.0 2.0 1.0 38 KB

Simple golang error handling with classification primitives.

License: Apache License 2.0

Go 100.00%
golang errors classification interfaces neuron golang-error

errors's Introduction

Neuron Logo

Errors Go Report Card GoDoc Build Status Coverage Status License

Package errors provides simple golang error and classification primitives.

Class

The package defines blazingly fast classification system. A Class is an uint32 wrapper, composed of the Major, Minor and Index subclassifications. Each subclassifaction has different bitwise length. A major is composed of 8, minor 10 and index of 14 bits - total 32bits.

Example:

 00000010101000101000010011001111 which decomposes into:
 00000010 - major (8 bit)
         1010001010 - minor (10 bit)
                   00010011001111 - index (14 bit)

The class concept was inspired by the need of multiple errors with the same logic but different messages.

A class might be composed in three different ways:

  • Major only - the class is Major singleton.
  • Major, Minor only - classes that don't need triple subclassification divison.
  • Major, Minor, Index - classes that decomposes

Use NewMajor or MustNewMajor functions to create Major, NewMinor or MustNewMinor for new Minor and NewIndex or MustNewIndex for new Index.

Interfaces

The package provides simple error handling interfaces and functions. It allows to create simple and detailed classified errors.

ClassError

A ClassError is the interface that provides error classification with theClass method.

DetailedError

DetailedError is the interface used for errors that stores and handles human readable details, contains it's instance id and runtime call operation. Implements ClassError, Detailer, Operationer, Indexer, error interfaces.

Detailer

Detailer interface allows to set and get the human readable details - full sentences.

Operationer

OperationError is the interface used to get the runtime operation information.

Indexer

Indexer is the interface used to obtain 'ID' for each error instance.

Error handling

This package contains two error structure implementations:

Simple Error

A simple error implements ClassError interface. It is lightweight error that contains only a message and it's class.

Created by the New and Newf functions.

Example:

import "github.com/neuronlabs/errors"
// let's assume we have some ClassInvalidRequest already defined.
var ClassInvalidInput errors.Class

func createValue(input int) error {
    if input < 0 {
        return errors.New(ClassInvalidInput, "provided input lower than zero")
    }

    if input > 50 {
        return errors.Newf(ClassInvalidInput, "provided input value: '%d' is not valid", input) 
    }
    // do the logic here
    return nil
}

Detailed Error

The detailed error struct (detailedError) implements DetailedError.

It contains a lot of information about given error instance:

  • Human readable Details
  • Runtime function call Operations
  • Unique error instance ID

In order to create detailed error use the NewDet or NewDetf functions.

Example

import (
    "fmt"
    "os"

    "github.com/neuronlabs/errors"
)

var (
    ClInputInvalidValue errors.Class
    ClInputNotProvided  errors.Class
)

func init() {
    initClasses()
}

func initClasses() {
    inputMjr := errors.MustNewMajor()
    invalidValueMnr := errors.MustNewMinor(inputMjr)
    ClInputInvalidValue = errors.MustNewMinorClass(inputMjr, invalidValueMnr)
    
    inputNotProvidedMnr := errors.MustNewMinor(inputMjr)
    ClInputNotProvided = errors.MustNewMinorClass(inputMjr, inputNotProvidedMnr)
}


func main() {
    input, err := getInput()
    if err == nil {
        // Everything is fine.
        os.Exit(0)
    }

    if classed, ok := err.(errors.ClassError); ok {
        if classed.Class() == ClInputNotProvided {
            fmt.Println("No required integer arguments provided.")
            os.Exit(1)
        }
    }

    var details string
    detailed, ok := err.(errors.DetailedError)
    if ok {
        details = detailed.Details()
    } else {
        details = err.Error()
    }
    fmt.Printf("Invalid input value provided: '%s'\n", details)
    os.Exit(1)    
}


func checkInput(input int) error {
    if input < 0 {
        err := errors.NewDet(ClassInputInvalidValue, "provided input lower than zero")        
        err.SetDetailsf("The input value provided to the function is invalid. The value must be greater than zero.")
        return err
    }

    if input > 50 {
        err := errors.NewDetf(ClassInvalidInput, "provided input value: '%d' is not valid", input) 
        err.SetDetailsf("The input value: '%d' provided to the function is invalid. The value can't be greater than '50'.", input)
        return err
    }
    // do the logic here
    return nil
}



func getInput() (int, error) {
    if len(os.Args) == 0 {
        return errors.New(ClInputNotProvided, "no input provided")
    }

    input, err := strconv.Atoi(os.Args[0])
    if err != nil {
        err := errors.NewDetf(ClInputInvalidValue, "provided input is not an integer")        
        err.SetDetail(err.Error())
        return 0, err
    }

    if err = checkInput(input); err != nil {
        return 0, err
    }
    return input, nil
}

Links

errors's People

Contributors

kucjac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

errors's Issues

[BUG] On creation check if subclass reach it’s limit

Describe the problem
In case there are so many subclasses that the integer value is greater than allowable the New* functions should return errors.

Describe the solution
Check if the top level value are not reached while creating new subclasses instances. The functions should not allow to create the Majors that are invalid - if the previous value is MaxUint32 then the next one would be zero. In case of Minors and Indexes it should check if the value isn’t greater than allowable.

Sent with GitHawk

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.