Skip to content
This repository has been archived by the owner on Dec 11, 2024. It is now read-only.

Commit

Permalink
PLF-95 Move xyerror to the new repository
Browse files Browse the repository at this point in the history
  • Loading branch information
huykingsofm committed Sep 1, 2022
0 parents commit 6467053
Show file tree
Hide file tree
Showing 16 changed files with 660 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#### Issue

- Jira or Github issue link.

#### Description

- Problem, Solution.

#### Changes

- [ ] Fix bug
- [ ] New feature
- [ ] Documentation
- [ ] Backward incompatible change

#### Testing

- Describe about your test.

#### Checklist

- [ ] Check README.md.
- [ ] Check CHANGELOG.md
- [ ] Check comments.
34 changes: 34 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Test

on:
push:
branches: [ "dev" ]
pull_request:
branches: [ "dev" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18

- run: go mod tidy

- name: Test
run: go test -timeout 30s -v -race ./... -coverprofile=cover.out

- name: Upload to Codacy
env:
CODACY_API_TOKEN: ${{ secrets.CODACY_API_TOKEN }}
CODACY_ORGANIZATION_PROVIDER: gh
CODACY_USERNAME: xybor-x
CODACY_PROJECT_NAME: xyerror
run: bash <(curl -Ls https://coverage.codacy.com/get.sh) report --force-coverage-parser go -r cover.out

- name: Benchmark
run: go test -benchmem -run=^$ -bench . ./...
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Log files
*.log
*.log.*

# Profiling files
*.prof
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Developing

- Migrated from the [origin project](https://github.com/xybor/xyplatform).
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 xybor

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
207 changes: 207 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
[![Xybor founder](https://img.shields.io/badge/xybor-huykingsofm-red)](https://github.com/huykingsofm)
[![Go Reference](https://pkg.go.dev/badge/github.com/xybor-x/xyerror.svg)](https://pkg.go.dev/github.com/xybor-x/xyerror)
[![GitHub Repo stars](https://img.shields.io/github/stars/xybor-x/xyerror?color=yellow)](https://github.com/xybor-x/xyerror)
[![GitHub top language](https://img.shields.io/github/languages/top/xybor-x/xyerror?color=lightblue)](https://go.dev/)
[![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/xybor-x/xyerror)](https://go.dev/blog/go1.18)
[![GitHub release (release name instead of tag name)](https://img.shields.io/github/v/release/xybor-x/xyerror?include_prereleases)](https://github.com/xybor-x/xyerror/releases/latest)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/5fae4ad52c184d6dbec00f44312f20d6)](https://www.codacy.com/gh/xybor-x/xyerror/dashboard?utm_source=github.com&utm_medium=referral&utm_content=xybor-x/xyerror&utm_campaign=Badge_Grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/5fae4ad52c184d6dbec00f44312f20d6)](https://www.codacy.com/gh/xybor-x/xyerror/dashboard?utm_source=github.com&utm_medium=referral&utm_content=xybor-x/xyerror&utm_campaign=Badge_Coverage)
[![Go Report](https://goreportcard.com/badge/github.com/xybor-x/xyerror)](https://goreportcard.com/report/github.com/xybor-x/xyerror)

# Introduction

Package xyerror supports to define error types conveniently.

The error is inspired by the idea of Python `Exception`.

# Features

## Python Exception Idea

Xyerror defined an error type used to create other errors called `Class`, it is
equivalent to `Exception` class in Python.

`Class` creates `XyError` objects by using `New` method. It looks like
`Exception` class creates `Exception` instances. Example:

```golang
// xyerror
var xerr xyerror.XyError
xerr = xyerror.ValueError.New("value is invalid")
fmt.Println(xerr)
```

```python
# python
print(ValueError("value is invalid"))
```

A `Class` can "inherits" from another `Class`. Example:

```golang
// xyerror
var ZeroDivisionError = xyerror.ValueError.NewClass("ZeroDivisionError")
fmt.Println(ZeroDivisionError.New("do not divide by zero"))
```

```python
# python
class ZeroDivisionError(ValueError):
...
print(ZeroDivisionError("do not divide by zero"))
```

A `Class` also "inherits" from some `Class` instances. Example:

```golang
// xyerror
var ValueTypeError = xyerror.
Combine(xyerror.ValueError, xyerror.TypeError).
NewClass("ValueTypeError")
```

```python
# python
class ValueTypeError(ValueError, TypeError):
...
```

A `XyError` created by `Class` can compare to this `Class`.

```golang
// xyerror
func foo() error {
return xyerror.ValueError.New("value is invalid")
}

func bar() error {
if xerr := foo(); errors.Is(xerr, xyerror.ValueError) {
fmt.Println(xerr)
} else {
return xerr
}
return nil
}
```

```python
# python
def foo():
raise ValueError("value is invalid")

def bar():
try:
foo()
except ValueError as e:
print(e)
```

## Error Number

Every `Class` has its own unique number called `errno`. This number is used to
compare a `XyError` with a `Class`. All `XyError` instances created by the same
`Class` have the same `errno`.

## Module-oriented Error

Xyerror is tended to create module-oriented errors. `Errno` of all `Class`
instances in a module need to be the same prefix.

For example, `ValueError` and `TypeError` are in `Default` module. So their
`errno` should be 100001 and 100002, respectively. In this case, 100000 is the
prefix number of `Default` module.

Every module needs to create an object called `Generator` to create its error
`Class` instances. Prefix of module is a self-defined value, it must be
divisible by 100000 and not equal to other modules' prefix.

```golang
var egen = xyerror.Register("XyExample", 200000)
var (
FooError = egen.NewClass("FooError")
BarError = egen.NewClass("BarError")
)
```

# Example

```golang
package xyerror_test

import (
"errors"
"fmt"

"github.com/xybor-x/xyerror"
)

var exampleGen = xyerror.Register("example", 400000)

func ExampleClass() {
// To create a root Class, call Generator.NewClass with the name of Class.
var RootError = exampleGen.NewClass("RootError")

// You can create a class from another one.
var ChildError = RootError.NewClass("ChildError")

fmt.Println(RootError)
fmt.Println(ChildError)

// Output:
// [400001] RootError
// [400002] ChildError
}

func ExampleXyError() {
// You can compare a XyError with an Class by using the built-in method
// errors.Is.
var NegativeIndexError = xyerror.IndexError.NewClass("NegativeIndexError")

var err1 = xyerror.ValueError.New("some value error")
if errors.Is(err1, xyerror.ValueError) {
fmt.Println("err1 is a ValueError")
}
if !errors.Is(err1, NegativeIndexError) {
fmt.Println("err1 is not a NegativeIndexError")
}

var err2 = NegativeIndexError.Newf("some negative index error %d", -1)
if errors.Is(err2, NegativeIndexError) {
fmt.Println("err2 is a NegativeIndexError")
}
if errors.Is(err2, xyerror.IndexError) {
fmt.Println("err2 is a IndexError")
}
if !errors.Is(err2, xyerror.ValueError) {
fmt.Println("err2 is not a ValueError")
}

// Output:
// err1 is a ValueError
// err1 is not a NegativeIndexError
// err2 is a NegativeIndexError
// err2 is a IndexError
// err2 is not a ValueError
}

func ExampleGroup() {
// Group allows you to create a class with multiparents.
var KeyValueError = xyerror.
Combine(xyerror.KeyError, xyerror.ValueError).
NewClass(exampleGen, "KeyValueError")

var err = KeyValueError.New("something is wrong")

if errors.Is(err, xyerror.KeyError) {
fmt.Println("err is a KeyError")
}

if errors.Is(err, xyerror.ValueError) {
fmt.Println("err is a ValueError")
}

// Output:
// err is a KeyError
// err is a ValueError
}
```
Loading

0 comments on commit 6467053

Please sign in to comment.