Error code for cache module

This commit is contained in:
Ming Deng 2021-02-02 23:25:41 +08:00
parent a8bfd409ca
commit 1c69214142
7 changed files with 171 additions and 184 deletions

View File

@ -1 +1,5 @@
# Error Module
## Module code
- httplib 1
- cache 2

View File

@ -33,8 +33,9 @@ package cache
import (
"context"
"fmt"
"time"
"github.com/beego/beego/v2/core/berror"
)
// Cache interface contains all behaviors for cache adapter.
@ -78,7 +79,7 @@ var adapters = make(map[string]Instance)
// it panics.
func Register(name string, adapter Instance) {
if adapter == nil {
panic("cache: Register adapter is nil")
panic(berror.Error(NilCacheAdapter, "cache: Register adapter is nil").Error())
}
if _, ok := adapters[name]; ok {
panic("cache: Register called twice for adapter " + name)
@ -92,7 +93,7 @@ func Register(name string, adapter Instance) {
func NewCache(adapterName, config string) (adapter Cache, err error) {
instanceFunc, ok := adapters[adapterName]
if !ok {
err = fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapterName)
err = berror.Errorf(UnknownAdapter, "cache: unknown adapter name %s (forgot to import?)", adapterName)
return
}
adapter = instanceFunc()

View File

@ -1,46 +1,55 @@
package cache
import (
"fmt"
"math"
"github.com/beego/beego/v2/core/berror"
)
var (
ErrIncrementOverflow = berror.Error(IncrementOverflow, "this incr invocation will overflow.")
ErrDecrementOverflow = berror.Error(DecrementOverflow, "this decr invocation will overflow.")
ErrNotIntegerType = berror.Error(NotIntegerType, "item val is not (u)int (u)int32 (u)int64")
)
func incr(originVal interface{}) (interface{}, error) {
switch val := originVal.(type) {
case int:
tmp := val + 1
if val > 0 && tmp < 0 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrIncrementOverflow
}
return tmp, nil
case int32:
if val == math.MaxInt32 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrIncrementOverflow
}
return val + 1, nil
case int64:
if val == math.MaxInt64 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrIncrementOverflow
}
return val + 1, nil
case uint:
tmp := val + 1
if tmp < val {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrIncrementOverflow
}
return tmp, nil
case uint32:
if val == math.MaxUint32 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrIncrementOverflow
}
return val + 1, nil
case uint64:
if val == math.MaxUint64 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrIncrementOverflow
}
return val + 1, nil
default:
return nil, fmt.Errorf("item val is not (u)int (u)int32 (u)int64")
return nil, ErrNotIntegerType
}
}
@ -49,35 +58,35 @@ func decr(originVal interface{}) (interface{}, error) {
case int:
tmp := val - 1
if val < 0 && tmp > 0 {
return nil, fmt.Errorf("decrement would overflow")
return nil, ErrDecrementOverflow
}
return tmp, nil
case int32:
if val == math.MinInt32 {
return nil, fmt.Errorf("decrement would overflow")
return nil, ErrDecrementOverflow
}
return val - 1, nil
case int64:
if val == math.MinInt64 {
return nil, fmt.Errorf("decrement would overflow")
return nil, ErrDecrementOverflow
}
return val - 1, nil
case uint:
if val == 0 {
return nil, fmt.Errorf("decrement would overflow")
return nil, ErrDecrementOverflow
}
return val - 1, nil
case uint32:
if val == 0 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrDecrementOverflow
}
return val - 1, nil
case uint64:
if val == 0 {
return nil, fmt.Errorf("increment would overflow")
return nil, ErrDecrementOverflow
}
return val - 1, nil
default:
return nil, fmt.Errorf("item val is not (u)int (u)int32 (u)int64")
return nil, ErrNotIntegerType
}
}

View File

@ -4,6 +4,8 @@ import (
"math"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
)
func TestIncr(t *testing.T) {
@ -11,116 +13,65 @@ func TestIncr(t *testing.T) {
var originVal interface{} = int(1)
var updateVal interface{} = int(2)
val, err := incr(originVal)
if err != nil {
t.Errorf("incr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("incr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = incr(int(1<<(strconv.IntSize-1) - 1))
if err == nil {
t.Error("incr failed")
return
}
assert.Equal(t, ErrIncrementOverflow, err)
// int32
originVal = int32(1)
updateVal = int32(2)
val, err = incr(originVal)
if err != nil {
t.Errorf("incr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("incr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = incr(int32(math.MaxInt32))
if err == nil {
t.Error("incr failed")
return
}
assert.Equal(t, ErrIncrementOverflow, err)
// int64
originVal = int64(1)
updateVal = int64(2)
val, err = incr(originVal)
if err != nil {
t.Errorf("incr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("incr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = incr(int64(math.MaxInt64))
if err == nil {
t.Error("incr failed")
return
}
assert.Equal(t, ErrIncrementOverflow, err)
// uint
originVal = uint(1)
updateVal = uint(2)
val, err = incr(originVal)
if err != nil {
t.Errorf("incr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("incr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = incr(uint(1<<(strconv.IntSize) - 1))
if err == nil {
t.Error("incr failed")
return
}
assert.Equal(t, ErrIncrementOverflow, err)
// uint32
originVal = uint32(1)
updateVal = uint32(2)
val, err = incr(originVal)
if err != nil {
t.Errorf("incr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("incr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = incr(uint32(math.MaxUint32))
if err == nil {
t.Error("incr failed")
return
}
assert.Equal(t, ErrIncrementOverflow, err)
// uint64
originVal = uint64(1)
updateVal = uint64(2)
val, err = incr(originVal)
if err != nil {
t.Errorf("incr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("incr failed, expect %v, but %v actually", updateVal, val)
return
}
_, err = incr(uint64(math.MaxUint64))
if err == nil {
t.Error("incr failed")
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = incr(uint64(math.MaxUint64))
assert.Equal(t, ErrIncrementOverflow, err)
// other type
_, err = incr("string")
if err == nil {
t.Error("incr failed")
return
}
assert.Equal(t, ErrNotIntegerType, err)
}
func TestDecr(t *testing.T) {
@ -128,114 +79,62 @@ func TestDecr(t *testing.T) {
var originVal interface{} = int(2)
var updateVal interface{} = int(1)
val, err := decr(originVal)
if err != nil {
t.Errorf("decr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("decr failed, expect %v, but %v actually", updateVal, val)
return
}
_, err = decr(int(-1 << (strconv.IntSize - 1)))
if err == nil {
t.Error("decr failed")
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = decr(int(-1 << (strconv.IntSize - 1)))
assert.Equal(t, ErrDecrementOverflow, err)
// int32
originVal = int32(2)
updateVal = int32(1)
val, err = decr(originVal)
if err != nil {
t.Errorf("decr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("decr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = decr(int32(math.MinInt32))
if err == nil {
t.Error("decr failed")
return
}
assert.Equal(t, ErrDecrementOverflow, err)
// int64
originVal = int64(2)
updateVal = int64(1)
val, err = decr(originVal)
if err != nil {
t.Errorf("decr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("decr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = decr(int64(math.MinInt64))
if err == nil {
t.Error("decr failed")
return
}
assert.Equal(t, ErrDecrementOverflow, err)
// uint
originVal = uint(2)
updateVal = uint(1)
val, err = decr(originVal)
if err != nil {
t.Errorf("decr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("decr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = decr(uint(0))
if err == nil {
t.Error("decr failed")
return
}
assert.Equal(t, ErrDecrementOverflow, err)
// uint32
originVal = uint32(2)
updateVal = uint32(1)
val, err = decr(originVal)
if err != nil {
t.Errorf("decr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("decr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = decr(uint32(0))
if err == nil {
t.Error("decr failed")
return
}
assert.Equal(t, ErrDecrementOverflow, err)
// uint64
originVal = uint64(2)
updateVal = uint64(1)
val, err = decr(originVal)
if err != nil {
t.Errorf("decr failed, err: %s", err.Error())
return
}
if val != updateVal {
t.Errorf("decr failed, expect %v, but %v actually", updateVal, val)
return
}
assert.Nil(t, err)
assert.Equal(t, val, updateVal)
_, err = decr(uint64(0))
if err == nil {
t.Error("decr failed")
return
}
assert.Equal(t, ErrDecrementOverflow, err)
// other type
_, err = decr("string")
if err == nil {
t.Error("decr failed")
return
}
assert.Equal(t, ErrNotIntegerType, err)
}

48
client/cache/error_code.go vendored Normal file
View File

@ -0,0 +1,48 @@
// Copyright 2021 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cache
import (
"github.com/beego/beego/v2/core/berror"
)
var NilCacheAdapter = berror.DefineCode(4002001, moduleName, "NilCacheAdapter", `
It means that you register cache adapter by pass nil.
A cache adapter is an instance of Cache interface.
`)
var DuplicateAdapter = berror.DefineCode(4002002, moduleName, "DuplicateAdapter", `
You register two adapter with same name. In beego cache module, one name one adapter.
Once you got this error, please check the error stack, search adapter
`)
var UnknownAdapter = berror.DefineCode(4002003, moduleName, "UnknownAdapter", `
Unknown adapter, do you forget to register the adapter?
You must register adapter before use it. For example, if you want to use redis implementation,
you must import the cache/redis package.
`)
var IncrementOverflow = berror.DefineCode(4002004, moduleName, "IncrementOverflow", `
The increment operation will overflow.
`)
var DecrementOverflow = berror.DefineCode(4002005, moduleName, "DecrementOverflow", `
The decrement operation will overflow.
`)
var NotIntegerType = berror.DefineCode(4002006, moduleName, "NotIntegerType", `
The type of value is not (u)int (u)int32 (u)int64.
When you want to call Incr or Decr function of Cache API, you must confirm that the value's type is one of (u)int (u)int32 (u)int64.
`)

33
client/cache/file.go vendored
View File

@ -73,22 +73,31 @@ func (fc *FileCache) StartAndGC(config string) error {
if err != nil {
return err
}
if _, ok := cfg["CachePath"]; !ok {
cfg["CachePath"] = FileCachePath
const cpKey = "CachePath"
const fsKey = "FileSuffix"
const dlKey = "DirectoryLevel"
const eeKey = "EmbedExpiry"
if _, ok := cfg[cpKey]; !ok {
cfg[cpKey] = FileCachePath
}
if _, ok := cfg["FileSuffix"]; !ok {
cfg["FileSuffix"] = FileCacheFileSuffix
if _, ok := cfg[fsKey]; !ok {
cfg[fsKey] = FileCacheFileSuffix
}
if _, ok := cfg["DirectoryLevel"]; !ok {
cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel)
if _, ok := cfg[dlKey]; !ok {
cfg[dlKey] = strconv.Itoa(FileCacheDirectoryLevel)
}
if _, ok := cfg["EmbedExpiry"]; !ok {
cfg["EmbedExpiry"] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10)
if _, ok := cfg[eeKey]; !ok {
cfg[eeKey] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10)
}
fc.CachePath = cfg["CachePath"]
fc.FileSuffix = cfg["FileSuffix"]
fc.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"])
fc.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"])
fc.CachePath = cfg[cpKey]
fc.FileSuffix = cfg[fsKey]
fc.DirectoryLevel, _ = strconv.Atoi(cfg[dlKey])
fc.EmbedExpiry, _ = strconv.Atoi(cfg[eeKey])
fc.Init()
return nil

17
client/cache/module.go vendored Normal file
View File

@ -0,0 +1,17 @@
// Copyright 2021 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cache
const moduleName = "cache"