Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

76
library/ecode/BUILD Normal file
View File

@@ -0,0 +1,76 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"ecode_test.go",
"status_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["manual"],
deps = [
"//library/ecode/internal/types:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
],
)
go_library(
name = "go_default_library",
srcs = [
"bbq_ecode.go",
"common_ecode.go",
"ecode.go",
"ep_ecode.go",
"live_ecode.go",
"main_ecode.go",
"open_ecode.go",
"status.go",
],
importpath = "go-common/library/ecode",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/ecode/internal/types:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
"@com_github_golang_protobuf//ptypes:go_default_library_gen",
],
)
go_test(
name = "go_default_xtest",
srcs = ["example_test.go"],
tags = ["automanaged"],
deps = [
"//library/ecode:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//library/ecode/internal/types:all-srcs",
"//library/ecode/pb:all-srcs",
"//library/ecode/tip:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,4 @@
##### v1.1
> 添加 ecode.Status
##### v1.0.0
> 增加bbq错误码

View File

@@ -0,0 +1,8 @@
# Owner
all
# Author
all
# Reviewer
all

9
library/ecode/OWNERS Normal file
View File

@@ -0,0 +1,9 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- anyone
labels:
- library
- library/ecode
options:
no_parent_owners: true

114
library/ecode/bbq_ecode.go Normal file
View File

@@ -0,0 +1,114 @@
package ecode
// bbq ecode interval is [5000000,6000000)
var (
CheckInviteCodeErr = New(3001016) // 检查邀请码失败(特殊处理请勿修改) todo
//Common [5000000,5001000)
Common = New(5000000)
TypeDismatch = New(5000001) // 类型不匹配
ExternalErr = New(5000002) // 外部错误
ReqParamErr = New(5000003) // 参数错误
BBQSystemErr = New(5000004) // 用于一些异常请求
BBQNoBindPhone = New(5000005) // 未绑定手机号
BBQUserBanned = New(5000006) // 已被封禁,无法进行相关操作,如有疑问可在“设置-吐槽”中进行反馈
ArchiveDatabusNilErr = New(5000007) // 预发环境不配置稿件databus
//Search [5001000,5002000)
SearchCreateIndexErr = New(5001000) // 创建索引失败
SearchVideoDataErr = New(5001001) // 获取视频信息失败
//web [5002000,5003000)
CommentClosed = New(5002001) // 评论已关闭
VideoUnExists = New(5002003) // 视频不存在
VideoUnReachable = New(5002004) // 视频不存在,由于状态原因不可访问
VideoInAudit = New(5002005) // 视频审核中
InviteCodeInvalid = New(5002014) // 无效邀请码
InviteCodeUsed = New(5002015) // 邀请码已使用
CommentForbidden = New(5002021) // 禁止评论
CommentTooShort = New(5002023) // 评论过短
CommentTooLong = New(5002024) // 评论过长
SvNotReachable = New(5002025)
NoticeTypeErr = New(5002026) // 通知类型错误
CommentForbidLike = New(5002027) // 禁止赞或踩
CommentLengthIllegal = New(5002028) // 评论长度不合法
//video-service [5003000,5004000)
UnKnownBPS = New(5003000) // 未知码率
SyncBVCFail = New(5003001) // 同步bvc转码失败
VideoDelFail = New(5003002) // 视频删除失败,不能删除别人的视频
// UserLike [5005000, 5005100]
UserLike = New(5005000) // UserLike [5005000, 5005100]
AddUserLikeErr = New(5005001) // 点赞失败
CancelUserLikeErr = New(5005002) // 取消点赞失败
// UserInfo [5005100, 5005200]
UserInfo = New(5005100) // UserInfo
BatchUserTooLong = New(5005101) // 用户批量请求太多
UPMIDNotExists = New(5005102) // up主不存在
GetUserBaseErr = New(5005103) // 获取用户信息失败
EditUserBaseErr = New(5005104) // 更新用户基础信息失败
UserUnameSpecial = New(5005105) // 昵称包含特殊字符
UserUnameLength = New(5005106) // 昵称长度不符合
UserUnameExisted = New(5005107) // 昵称已被占用
UserUnameFilterErr = New(5005108) // 昵称包含敏感词
UserUnamePrefixErr = New(5005109) // 该昵称无法注册
// UserRelation [5005200, 5005300]
UserRelation = New(5005200)
AddUserFollowErr = New(5005201) // 关注失败,请稍后重试
CancelUserFollowErr = New(5005202) // 取消关注失败,请稍后重试
UserFollowLimitErr = New(5005203) // 关注失败,关注已达上限
FollowMyselfErr = New(5005204) // 不能关注自己
UserAlreadyBlackFollowErr = New(5005205) // 关注失败,请将用户移出黑名单后重试
UserBlackLimitErr = New(5005206) // 拉黑失败,黑名单已达上限
UserBlackErr = New(5005207) // 黑名单请求系统错误
UserBlackSelfErr = New(5005208) // 拉黑失败,不能拉黑自己
// Danmu [5005300, 5005400]
Danmu = New(5005300)
FilterErr = New(5005301) // 弹幕包含敏感词
DanmuGetErr = New(5005302) // 弹幕获取失败
DanmuPostErr = New(5005303) // 弹幕发送失败
DanmuLimitErr = New(5005304) // 该视频暂时无法发送弹幕
// Comment [5005400, 5005500]
Comment = New(5005400)
CommentFilterErr = New(5005401) // 评论包含敏感词
CommentMissErr = New(5005402) // 评论不见了
CommentLengthErr = New(5005403) // 评论需要2-96字
CommentOptLimitErr = New(5005404) // 操作太快了,休息一下
CommentLimithErr = New(5005405) // 该视频暂时无法发送评论
// report [5005500, 5005599]
ReportDanmuError = New(5005501) // 弹幕举报失败
//Upload [5005600, 5005700]
Upload = New(5005600)
UploadFailed = New(5005601) //上传失败
// Topic [5005700, 5005800]
Topic = New(5005700)
TopicReqParamErr = New(5005701) // 参数错误
TopicNumTooManyErr = New(5005702) // 一次性插入db的话题数量太大
TopicNameLenErr = New(5005703) // 话题长度太长
TopicIDErr = New(5005704) // 话题ID错误
TopicIDNotFound = New(5005705) // 话题ID没找到
TopicStateErr = New(5005706) // 话题为下架状态
TopicTooManyInOneVideo = New(5005707) // 一个视频的话题数量太多了
TopicDescLenErr = New(5005708) // 话题描述长度太长
TopicInsertErr = New(5005709) // 话题插入失败
TopicVideoStateErr = New(5005721) // 话题视频状态错误
)
// 可以取消点赞的状态
var svLikeCancelAvailableState = map[error]bool{
VideoUnReachable: true,
VideoInAudit: true,
}
// IsCancelSvLikeAvailable 可以取消点赞的状态
func IsCancelSvLikeAvailable(err error) (available bool) {
_, available = svLikeCancelAvailableState[err]
return
}

View File

@@ -0,0 +1,57 @@
package ecode
// All common ecode
var (
OK = add(0) // 正确
AppKeyInvalid = add(-1) // 应用程序不存在或已被封禁
AccessKeyErr = add(-2) // Access Key错误
SignCheckErr = add(-3) // API校验密匙错误
MethodNoPermission = add(-4) // 调用方对该Method没有权限
NoLogin = add(-101) // 账号未登录
UserDisabled = add(-102) // 账号被封停
LackOfScores = add(-103) // 积分不足
LackOfCoins = add(-104) // 硬币不足
CaptchaErr = add(-105) // 验证码错误
UserInactive = add(-106) // 账号未激活
UserNoMember = add(-107) // 账号非正式会员或在适应期
AppDenied = add(-108) // 应用不存在或者被封禁
MobileNoVerfiy = add(-110) // 未绑定手机
CsrfNotMatchErr = add(-111) // csrf 校验失败
ServiceUpdate = add(-112) // 系统升级中
UserIDCheckInvalid = add(-113) // 账号尚未实名认证
UserIDCheckInvalidPhone = add(-114) // 请先绑定手机
UserIDCheckInvalidCard = add(-115) // 请先完成实名认证
NotModified = add(-304) // 木有改动
TemporaryRedirect = add(-307) // 撞车跳转
RequestErr = add(-400) // 请求错误
Unauthorized = add(-401) // 未认证
AccessDenied = add(-403) // 访问权限不足
NothingFound = add(-404) // 啥都木有
MethodNotAllowed = add(-405) // 不支持该方法
Conflict = add(-409) // 冲突
ServerErr = add(-500) // 服务器错误
ServiceUnavailable = add(-503) // 过载保护,服务暂不可用
Deadline = add(-504) // 服务调用超时
LimitExceed = add(-509) // 超出限制
FileNotExists = add(-616) // 上传文件不存在
FileTooLarge = add(-617) // 上传文件太大
FailedTooManyTimes = add(-625) // 登录失败次数太多
UserNotExist = add(-626) // 用户不存在
PasswordTooLeak = add(-628) // 密码太弱
UsernameOrPasswordErr = add(-629) // 用户名或密码错误
TargetNumberLimit = add(-632) // 操作对象数量限制
TargetBlocked = add(-643) // 被锁定
UserLevelLow = add(-650) // 用户等级太低
UserDuplicate = add(-652) // 重复的用户
AccessTokenExpires = add(-658) // Token 过期
PasswordHashExpires = add(-662) // 密码时间戳过期
AreaLimit = add(-688) // 地理区域限制
CopyrightLimit = add(-689) // 版权限制
FailToAddMoral = add(-701) // 扣节操失败
Degrade = add(-1200) // 被降级过滤的请求
RPCNoClient = add(-1201) // rpc服务的client都不可用
RPCNoAuth = add(-1202) // rpc服务的client没有授权
)

123
library/ecode/ecode.go Normal file
View File

@@ -0,0 +1,123 @@
package ecode
import (
"fmt"
"strconv"
"sync/atomic"
"github.com/pkg/errors"
)
var (
_messages atomic.Value // NOTE: stored map[string]map[int]string
_codes = map[int]struct{}{} // register codes.
)
// Register register ecode message map.
func Register(cm map[int]string) {
_messages.Store(cm)
}
// New new a ecode.Codes by int value.
// NOTE: ecode must unique in global, the New will check repeat and then panic.
func New(e int) Code {
if e <= 0 {
panic("business ecode must greater than zero")
}
return add(e)
}
func add(e int) Code {
if _, ok := _codes[e]; ok {
panic(fmt.Sprintf("ecode: %d already exist", e))
}
_codes[e] = struct{}{}
return Int(e)
}
// Codes ecode error interface which has a code & message.
type Codes interface {
// sometimes Error return Code in string form
// NOTE: don't use Error in monitor report even it also work for now
Error() string
// Code get error code.
Code() int
// Message get code message.
Message() string
//Detail get error detail,it may be nil.
Details() []interface{}
// Equal for compatible.
// Deprecated: please use ecode.EqualError.
Equal(error) bool
}
// A Code is an int error code spec.
type Code int
func (e Code) Error() string {
return strconv.FormatInt(int64(e), 10)
}
// Code return error code
func (e Code) Code() int { return int(e) }
// Message return error message
func (e Code) Message() string {
if cm, ok := _messages.Load().(map[int]string); ok {
if msg, ok := cm[e.Code()]; ok {
return msg
}
}
return e.Error()
}
// Details return details.
func (e Code) Details() []interface{} { return nil }
// Equal for compatible.
// Deprecated: please use ecode.EqualError.
func (e Code) Equal(err error) bool { return EqualError(e, err) }
// Int parse code int to error.
func Int(i int) Code { return Code(i) }
// String parse code string to error.
func String(e string) Code {
if e == "" {
return OK
}
// try error string
i, err := strconv.Atoi(e)
if err != nil {
return ServerErr
}
return Code(i)
}
// Cause cause from error to ecode.
func Cause(e error) Codes {
if e == nil {
return OK
}
ec, ok := errors.Cause(e).(Codes)
if ok {
return ec
}
return String(e.Error())
}
// Equal equal a and b by code int.
func Equal(a, b Codes) bool {
if a == nil {
a = OK
}
if b == nil {
b = OK
}
return a.Code() == b.Code()
}
// EqualError equal error
func EqualError(code Codes, err error) bool {
return Cause(err).Code() == code.Code()
}

View File

@@ -0,0 +1,78 @@
package ecode
import (
"testing"
)
func TestNew(t *testing.T) {
defer func() {
errStr := recover()
if errStr != "ecode: 1 already exist" {
t.Logf("New duplicate ecode should cause panic")
t.FailNow()
}
}()
var _ error = New(1)
var _ error = New(2)
var _ error = New(1)
}
func TestErrMessage(t *testing.T) {
e1 := New(3)
if e1.Error() != "3" {
t.Logf("ecode message should be `3`")
t.FailNow()
}
if e1.Message() != "3" {
t.Logf("unregistered ecode message should be ecode number")
t.FailNow()
}
Register(map[int]string{3: "testErr"})
if e1.Message() != "testErr" {
t.Logf("registered ecode message should be `testErr`")
t.FailNow()
}
}
func TestCause(t *testing.T) {
e1 := New(4)
var err error = e1
e2 := Cause(err)
if e2.Code() != 4 {
t.Logf("parsed error code should be 4")
t.FailNow()
}
}
func TestInt(t *testing.T) {
e1 := Int(1)
if e1.Code() != 1 {
t.Logf("int parsed error code should be 1")
t.FailNow()
}
if e1.Error() != "1" || e1.Message() != "1" {
t.Logf("int parsed error string should be `1`")
t.FailNow()
}
}
func TestString(t *testing.T) {
eStr := String("123")
if eStr.Code() != 123 {
t.Logf("string parsed error code should be 123")
t.FailNow()
}
if eStr.Error() != "123" || eStr.Message() != "123" {
t.Logf("string parsed error string should be `123`")
t.FailNow()
}
eStr = String("test")
if eStr.Code() != -500 {
t.Logf("invalid string parsed error code should be -500")
t.FailNow()
}
if eStr.Error() != "-500" || eStr.Message() != "-500" {
t.Logf("invalid string parsed error string should be `-500`")
t.FailNow()
}
}

90
library/ecode/ep_ecode.go Normal file
View File

@@ -0,0 +1,90 @@
package ecode
// ep ecode interval is [0,990000]
var (
//merlin/paas
MerlinInvalidClusterErr = New(80001) // 集群不合法
MerlinPaasRequestErr = New(80002) // Paas 请求错误
//merlin/tree
MerlinGetUserTreeFailed = New(80010) //获取 tree 节点失败
MerlinTreeResponseErr = New(80011) //请求 Tree 失败
MerlinShouldTreeFullPath = New(80012) //节点不合法
MerlinTreeRequestErr = New(80013) //服务树请求错误
MerlinLoseTreeContainerNodeErr = New(80014) //当前节点下不存在 dev/container 子节点
MerlinUserNoAccessTreeNode = New(80034) //用户没有该服务树节点权限
//merlin
MerlinDuplicateMachineNameErr = New(81001) // 机器名称重复
MerlinInvalidMachineAmountErr = New(81002) //机器数量不合法
MerlinInvalidNodeAmountErr = New(81003) //挂载节点数必须大于0且不大于10
MerlinUpdateNodeErr = New(81004) //更新节点失败
MerlinCanNotBeDel = New(81040) //创建状态机器无法删除
//other
MerlinIllegalPageNumErr = New(89001) //分页页码不合法
MerlinIllegalPageSizeErr = New(89002) //分页大小不合法
MerlinDelayMachineErr = New(89010) //机器自主延期失败
MerlinApplyMachineErr = New(89011) //机器申请延期失败
MerlinCancelMachineErr = New(89012) //机器取消延期失败
MerlinAuditMachineErr = New(89013) //机器审核延期失败
MerlinApplyMachineByApplyEndTimeMore3MErr = New(89014) //机器申请延期失败
//hubbili
MerlinHubRequestErr = New(89015) //请求bilihub失败
MerlinHubNoRight = New(89016) //没有权限执行
MerlinImagePullErr = New(89017) //下载镜像失败
MerlinImagePushErr = New(89018) //上传镜像失败
MerlinImageTagErr = New(89019) //Tag镜像失败
MerlinSnapshotInDoingErr = New(89024) //快照进行中
MerlinNoHubAccount = New(89026) //该用户没有Hub账号
MerlinDuplicateImageNameErr = New(89028) //镜像名称重复
MerlinMachine2ImageInDoingErr = New(89029) //机器转镜像进行中
MerlinMachineImageNotSameErr = New(89030) //镜像名称不一致
MerlinDeviceNotBind = New(89020) //设备未绑定
MerlinDeviceFarmErr = New(89021) //DeviceFarm Error
MerlinDeviceFarmMachineStatusErr = New(89025) //Merlin Device Farm Machine StatusErr
MerlinDeviceIsNotRealMachineErr = New(89031) //该操作只支持真机
MerlinDeviceIsLendOut = New(89032) //真机需在机架上才能操作
MerlinDeviceNoRight = New(89033) //无权限操作
// user
MerlinUserNotExist = New(89034) //用户不存在
MartheBuglyErr = New(89022) //MartheBuglyErr
MartheTapdErr = New(89023) //Tapd请求错误
MartheTapdResDataErr = New(89050) //Tapd返回数据错误
MartheTaskInRunning = New(89047) //有任务正在执行
MartheNoProjectInfo = New(89045)
MartheBugTaskInRunning = New(89041)
MartheDuplicateErr = New(81044) // 名称重复
MartheNoCookie = New(89042)
MartheCookieExpired = New(89043) //cookie过期
MartheFilterSqlError = New(89046) //过滤sql error.
MartheTimeConflictError = New(89048) //时间冲突.
//melloi/PaaS
MelloiPaasRequestErr = New(60002) // Paas 请求错误
MeilloiIllegalPageNumErr = New(60004) //分页页码不合法
MeilloillegalPageSizeErr = New(60005) //分页大小不合法
MelloiTreeRequestErr = New(60001) //Tree 请求错误
MelloiAdminExist = New(60003) //管理员存在
MelloiUpdateUserErr = New(60006) //更新用户权限
MelloiApplyRequestErr = New(60008) //申请请求错误
MelloiLabelRelationNotExist = New(60009) //标签关系存在
MelloiLabelCountErr = New(60010) //Label 数量超过2
MelloiLabelExistErr = New(60011) //Label数量存在
MelloiRunNotInTime = New(60012) //非压测时间段
MelloiJmeterGenerateErr = New(60013) //Jmeter脚本生成失败
MelloiProtoFileNotUploaded = New(60014) // proto文件没有上传
MelloiProtocError = New(60015) // protoc 编译失败
MelloiProtoJavaPluginError = New(60016) // protoc java插件编译失败
MelloiJavacCompileError = New(60017) // javac 编译失败
MelloiJarError = New(60018) // Jar打包失败
MelloiUrlParseError = New(60019) // URL 解析错误
MelloiBeyondFileSize = New(60020) // 文件太大
MelloiCopyFileErr = New(60021) // 文件复制错误
)

View File

@@ -0,0 +1,49 @@
package ecode_test
import (
"fmt"
"go-common/library/ecode"
"github.com/pkg/errors"
)
func Example_ecode_Message() {
_ = ecode.NotModified.Message()
}
func Example_ecode_Code() {
_ = ecode.NotModified.Code()
}
func Example_ecode_Error() {
_ = ecode.NotModified.Error()
}
func ExampleCause() {
err := errors.WithStack(ecode.AccessDenied)
ecode.Cause(err)
}
func ExampleInt() {
err := ecode.Int(500)
fmt.Println(err)
// Output:
// 500
}
func ExampleString() {
ecode.String("500")
}
// ExampleStack package error with stack.
func Example() {
err := errors.New("dao error")
errors.Wrap(err, "some message")
// package ecode with stack.
errCode := ecode.AccessDenied
err = errors.Wrap(errCode, "some message")
//get ecode from package error
code := errors.Cause(err).(ecode.Codes)
fmt.Printf("%d: %s\n", code.Code(), code.Message())
}

View File

@@ -0,0 +1,54 @@
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
proto_library(
name = "types_proto",
srcs = ["status.proto"],
tags = ["automanaged"],
deps = ["@com_google_protobuf//:any_proto"],
)
go_proto_library(
name = "types_go_proto",
compilers = ["@io_bazel_rules_go//proto:go_proto"],
importpath = "go-common/library/ecode/internal/types",
proto = ":types_proto",
tags = ["automanaged"],
deps = ["@io_bazel_rules_go//proto/wkt:any_go_proto"],
)
go_library(
name = "go_default_library",
srcs = [],
embed = [":types_go_proto"],
importpath = "go-common/library/ecode/internal/types",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"@com_github_golang_protobuf//proto:go_default_library",
"@io_bazel_rules_go//proto/wkt:any_go_proto",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,102 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: internal/types/status.proto
package types // import "go-common/library/ecode/internal/types"
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import any "github.com/golang/protobuf/ptypes/any"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Status struct {
// The error code see ecode.Code
Code int32 `protobuf:"varint,1,opt,name=code" json:"code,omitempty"`
// A developer-facing error message, which should be in English. Any
Message string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"`
// A list of messages that carry the error details. There is a common set of
// message types for APIs to use.
Details []*any.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Status) Reset() { *m = Status{} }
func (m *Status) String() string { return proto.CompactTextString(m) }
func (*Status) ProtoMessage() {}
func (*Status) Descriptor() ([]byte, []int) {
return fileDescriptor_status_88668d6b2bf80f08, []int{0}
}
func (m *Status) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Status.Unmarshal(m, b)
}
func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Status.Marshal(b, m, deterministic)
}
func (dst *Status) XXX_Merge(src proto.Message) {
xxx_messageInfo_Status.Merge(dst, src)
}
func (m *Status) XXX_Size() int {
return xxx_messageInfo_Status.Size(m)
}
func (m *Status) XXX_DiscardUnknown() {
xxx_messageInfo_Status.DiscardUnknown(m)
}
var xxx_messageInfo_Status proto.InternalMessageInfo
func (m *Status) GetCode() int32 {
if m != nil {
return m.Code
}
return 0
}
func (m *Status) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func (m *Status) GetDetails() []*any.Any {
if m != nil {
return m.Details
}
return nil
}
func init() {
proto.RegisterType((*Status)(nil), "bilibili.rpc.Status")
}
func init() { proto.RegisterFile("internal/types/status.proto", fileDescriptor_status_88668d6b2bf80f08) }
var fileDescriptor_status_88668d6b2bf80f08 = []byte{
// 220 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x8f, 0xb1, 0x4a, 0x04, 0x31,
0x10, 0x86, 0xd9, 0x5b, 0xbd, 0xc3, 0x9c, 0x85, 0x04, 0x8b, 0x55, 0x9b, 0xc5, 0x6a, 0x0b, 0x4d,
0x40, 0x4b, 0x2b, 0xcf, 0x17, 0x58, 0x22, 0x36, 0x76, 0x49, 0x6e, 0x2e, 0x04, 0x92, 0xcc, 0x92,
0xe4, 0x8a, 0xbc, 0x8e, 0x4f, 0x2a, 0x9b, 0x65, 0x41, 0x8b, 0x19, 0x66, 0x98, 0xff, 0xe7, 0xfb,
0x87, 0x3c, 0xd8, 0x90, 0x21, 0x06, 0xe9, 0x78, 0x2e, 0x13, 0x24, 0x9e, 0xb2, 0xcc, 0xe7, 0xc4,
0xa6, 0x88, 0x19, 0xe9, 0xb5, 0xb2, 0xce, 0xce, 0xc5, 0xe2, 0xa4, 0xef, 0xef, 0x0c, 0xa2, 0x71,
0xc0, 0xeb, 0x4d, 0x9d, 0x4f, 0x5c, 0x86, 0xb2, 0x08, 0x1f, 0x4f, 0x64, 0xfb, 0x59, 0x8d, 0x94,
0x92, 0x0b, 0x8d, 0x47, 0xe8, 0x9a, 0xbe, 0x19, 0x2e, 0x45, 0x9d, 0x69, 0x47, 0x76, 0x1e, 0x52,
0x92, 0x06, 0xba, 0x4d, 0xdf, 0x0c, 0x57, 0x62, 0x5d, 0x29, 0x23, 0xbb, 0x23, 0x64, 0x69, 0x5d,
0xea, 0xda, 0xbe, 0x1d, 0xf6, 0x2f, 0xb7, 0x6c, 0x81, 0xb0, 0x15, 0xc2, 0xde, 0x43, 0x11, 0xab,
0xe8, 0xf0, 0x45, 0x6e, 0x34, 0x7a, 0xf6, 0x37, 0xd6, 0x61, 0xbf, 0x90, 0xc7, 0xd9, 0x30, 0x36,
0xdf, 0x4f, 0x06, 0x9f, 0x35, 0x7a, 0x8f, 0x81, 0x3b, 0xab, 0xa2, 0x8c, 0x85, 0xc3, 0x9c, 0x82,
0xff, 0x7f, 0xf4, 0xad, 0xf6, 0x9f, 0x4d, 0x2b, 0xc6, 0x0f, 0xb5, 0xad, 0xb4, 0xd7, 0xdf, 0x00,
0x00, 0x00, 0xff, 0xff, 0x80, 0xa3, 0xc1, 0x82, 0x0d, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,23 @@
syntax = "proto3";
package bilibili.rpc;
import "google/protobuf/any.proto";
option go_package = "go-common/library/ecode/internal/types;types";
option java_multiple_files = true;
option java_outer_classname = "StatusProto";
option java_package = "com.bilibili.rpc";
option objc_class_prefix = "RPC";
message Status {
// The error code see ecode.Code
int32 code = 1;
// A developer-facing error message, which should be in English. Any
string message = 2;
// A list of messages that carry the error details. There is a common set of
// message types for APIs to use.
repeated google.protobuf.Any details = 3;
}

183
library/ecode/live_ecode.go Normal file
View File

@@ -0,0 +1,183 @@
package ecode
// 直播 号段  1000000 - 1999999
// 为防止定义重复,以及方便查找,各个服务错误码可直接选用一个段号
// 调用服务出错已选用一个段号,参见最后
var (
// wallet 1000000 - 1001999
CoinNotEnough = New(1000000)
PayFailed = New(1000001)
// live-test 100 2000 - 100 2999
RoomNotFound = New(1002001)
InvalidParam = New(1002002)
GetAllListRPCError = New(1002003)
GetAllListReturnError = New(1002004)
GetAllListSimpleJSONError = New(1002005)
AttentionRPCError = New(1002006)
AttentionReturnError = New(1002007)
UserTagRPCError = New(1002008)
UserTagReturnError = New(1002009)
UserTagRoomListRPCError = New(1002010)
UserTagRoomListReturnError = New(1002011)
SeaPatrolRPCError = New(1002012)
SeaPatrolReturnError = New(1002013)
ActivityRPCError = New(1002014)
ActivityReturnError = New(1002015)
ChangeGetAllListRPCError = New(1002016)
ChangeGetAllListReturnError = New(1002017)
ChangeGetAllListEmptyError = New(1002018)
SkyHorseError = New(1002019)
ChangeSkyHorseEmptyError = New(1002020)
GetRoomError = New(1002021)
GetRoomEmptyError = New(1002024)
RoomPendantError = New(1002022)
RoomPendantReturnError = New(1002023)
AttentionListRPCError = New(1002100)
RelationFrameWorkCallError = New(1002101)
RelationLiveRPCCodeError = New(1002102)
RelationFrameWorkGoRoutingError = New(1002103)
RoomGetStatusInfoRPCError = New(1002104)
GetMultipleRPCError = New(1002105)
RoomPendentRPCError = New(1002106)
PKIDRpcError = New(1002107)
UnliveAnchorReqParamsError = New(1002108)
LiveAnchorReqParamsError = New(1002109)
NeedLogIn = New(1002110)
RoomFrameWorkCallError = New(1002111)
RoomLiveRPCCodeError = New(1002112)
RoomFrameWorkGoRoutingError = New(1002113)
UserFrameWorkCallError = New(1002114)
UserLiveRPCCodeError = New(1002115)
UserFrameWorkGoRoutingError = New(1002116)
RecordRecordFrameWorkCallError = New(1002117)
RecordLiveRPCCodeError = New(1002118)
RecordFrameWorkGoRoutingError = New(1002119)
RoomNewsRecordFrameWorkCallError = New(1002120)
RoomNewsLiveRPCCodeError = New(1002121)
RoomNewsFrameWorkGoRoutingError = New(1002122)
RoomPendentFrameWorkCallError = New(1002123)
RoomPendentLiveRPCCodeError = New(1002124)
RoomPendentFrameWorkGoRoutingError = New(1002125)
PkIDRecordFrameWorkCallError = New(1002126)
PkIDLiveRPCCodeError = New(1002127)
PkIDFrameWorkGoRoutingError = New(1002128)
FansMedalFrameWorkCallError = New(1002129)
FansMedalLiveRPCCodeError = New(1002130)
FansMedalFrameWorkGoRoutingError = New(1002131)
GiftFrameWorkCallError = New(1002132)
GiftLiveRPCCodeError = New(1002133)
RoomGetRoomIDCodeRPCError = New(1002134)
LiveAnchorReqParamsNil = New(1002135)
GetGrayRuleError = New(1002136)
AccountGRPCError = New(1002137)
AccountGRPCFrameError = New(1002138)
LiveAnchorReqV2ParamsNil = New(1002139)
LiveAnchorReqV2ParamsError = New(1002140)
UserDHHRPCError = New(1002141)
UserDHHReturnError = New(1002142)
UserDHHDataNil = New(1002143)
XanchorGRPCError = New(1002150)
// resource 1003000 - 1003199
ResourceParamErr = New(1003001) // 参数传入错误
TimeForErr = New(1003002) // 时间格式错误
AddResourceErr = New(1003003) // 添加资源失败
RepdAddErr = New(1003004) // 添加平台已存在
SeltResErr = New(1003005) // 资源选择失败
EditResErr = New(1003006) // 编辑资源失败
DeviceError = New(1003007) // 参数<device>传入错误
OfflineResErr = New(1003008) // 下线资源失败
GetListResErr = New(1003009) // 获取资源列表失败
GetBannerErr = New(1003010) // 获取Banner配置失败
GetSplashErr = New(1003011) // 获取闪屏配置失败
CheckURLErr = New(1003012) // 链接格式错误
GetConfAdminErr = New(1003101) // 没有获取到配置
SetConfAdminErr = New(1003102) // 设置配置失败
// dm 1003200 - 1003399
DMallUser = New(1003200) // 系统正在维护(全员弹幕禁言)
DMUserLevel = New(1003201) // 系统正在维护(全员指定等级禁言)
RealName = New(1003202) // 实名认证才可以发言
PhoneBind = New(1003203) // 根据国家实名制认证的相关要求,您需要绑定手机号,才能继续进行操作。
PhoneReal = New(1003204) // 根据国家实名制认证的相关要求您需要换绑一个非170/171的手机号才能继续进行操作。
ShieldUser = New(1003205) // u (被播主过滤的用户)
ShieldContent = New(1003206) // k (被播主过滤的内容)
BlockUser = New(1003207) // 你在本房间被禁言
PayLive = New(1003208) // 非常抱歉,本场直播需要购票,即可参与互动(付费直播)
SecDMLimit = New(1003209) // msg in 1s(每秒发言限制)
DMSameMsgLimit = New(1003210) // msg repeat(消息重复)
DMLimitPerRoom = New(1003211) // max limit(单房间每秒限制)
MsgLengthLimit = New(1003212) // 超出限制长度
FilterLimit = New(1003213) // 内容非法(敏感词限制)
CountryLimit = New(1003214) // 你所在的地区暂无法发言(区域限制)
RoomLeverLimit = New(1003215) // 房间等级限制
RoomAllLimit = New(1003216) // 房间全员限制
RoomMedalLimit = New(1003217) // 房间勋章等级限制
DMServiceERR = New(1003218) // 依赖下游服务失败
// user 1004000 - 1004999
UidError = New(1004000) //Uid错误
UserNotFound = New(1004001) //找不到用户信息
// dao-anchor 1005000 - 1005999
DaoAnchorCheckAttrSubIdERROR = New(1005000) //找不到对应的标签子id
// user_ex 1006000 - 1006999
// gift 1007000 - 1007999
// xuser 1008000 - 1008999
XUserAddUserExpReqBizNotAllow = New(1008001)
XUserAddUserExpTypeNotAllow = New(1008002)
XUserAddUserExpNumNotAllow = New(1008003)
XUserAddUserExpUpdateDBError = New(1008004)
XUserAddUserExpParamsEmptyError = New(1008005)
XUserAddUserExpQueryAfterFail = New(1008006)
XUserAddAnchorUpdateDBError = New(1008007)
XUserAddRExpUpdateDBError = New(1008008)
XUserAddUserRExpQueryAfterFail = New(1008009)
XUserAddRoomAdminOverLimitError = New(1008020)
XUserAddRoomAdminIsAdminError = New(1008021)
XUserAddRoomAdminIsSilentError = New(1008022)
XUserAddRoomAdminNotAdminError = New(1008023)
XUserExpGetExpMcFail = New(1008024) // 获取用户经验缓存失败
XUserExpGetExpDBFail = New(1008025) // 获取用户经验缓回源db失败
XUserAddUExpGetParamsNil = New(1008026) // 添加用户经验缓入参为空
XUserGuardFetchRecentTopListFail = New(1008027) // 获取主播最近总督失败
// capusle 1009000 - 1008999
XLotteryCapsuleAreaParamErr = New(1009001)
XLotteryCapsuleSystemErr = New(1009002)
XLotteryCapsuleCoinNotEnough = New(1009003)
XLotteryCapsuleCoinNotChange = New(1009004)
XLotteryCapsulePoolNotChange = New(1009005)
XLotteryCapsulePoolNotOffline = New(1009006)
XLotteryCapsuleOperationFrequent = New(1009007)
// app-conf 1010000 - 1010100
AppConfKeyErr = New(1010000)
//验证码 1990000 - 1990100
VerifyNeed = New(1990000)
VerifyErr = New(1990001)
//网关层错误码 1100000 - 1101999
FILTERNOTPASS = New(1100000) //屏蔽词校验失败
UploadTokenGenErr = New(1100010) // Upload token 创建失败
UploadUploadErr = New(1100011) // 上传失败
UploadBucketErr = New(1100012) // 上传bucket错误
//调用服务出错 19001000 - 19001999
CallRoomError = New(19001000)
CallUserError = New(19001001)
CallRelationError = New(19001002)
CallFansMedalError = New(19001003)
CallMainMemberError = New(19001004)
CallResourceError = New(19001005)
CallMainFilterError = New(19001006)
CallDaoAnchorError = New(19001007)
)

1450
library/ecode/main_ecode.go Normal file

File diff suppressed because it is too large Load Diff

100
library/ecode/open_ecode.go Normal file
View File

@@ -0,0 +1,100 @@
package ecode
// common ecode
// 开放平台 2000000~2999999
// 票务的code码 2000000~2099999
var (
//销售-营销
TicketUnKnown = New(2000000) //未知错误
TicketParamInvalid = New(2000001) //参数错误
TicketRecordDupli = New(2000002) //重复插入
TicketRecordLost = New(2000003) //数据不存在
TicketPromotionLost = New(2000004) //活动不存在
TicketPromotionEnd = New(2000005) //活动结束
TicketPromotionRepeatJoin = New(2000006) //活动重复参加
TicketPromotionGroupLost = New(2000007) //拼团不存在
TicketPromotionGroupFull = New(2000008) //拼团人数已满
TicketPromotionGroupNotFull = New(2000009) //拼团人数未满
TicketPromotionOrderLost = New(2000010) //拼团订单不存在
TicketPromoExistSameTime = New(2000011) //同时间段存在已上架拼团活动
TicketAddPromoOrderFail = New(2000012) //添加活动订单失败
TicketAddPromoGroupFail = New(2000013) //添加拼团 团订单失败
TicketPromoGroupEnd = New(2000014) //拼团 团订单已失效
TicketUpdatePromoOrderFail = New(2000015) //更新拼团订单失败
TicketUpdatePromoGroupFail = New(2000016) //更新拼团 团订单失败
IllegalPromoOperate = New(2000017) //拼团 不支持的操作类型
PromoStatusChanged = New(2000018) //拼团状态无法变更
TicketPromoGroupStatusErr = New(2000019) //拼团状态不对
TicketPromoOrderTypeErr = New(2000020) //订单类型不对
PromoEditNotALlowed = New(2000021) //不可编辑
PromoEditFieldNotALlowed = New(2000022) //不可编辑部分字段
PromoExists = New(2000023) //拼团已存在
//销售-交易
TicketGetOidFail = New(2000101) //获取订单号失败
TicketExceedLimit = New(2000102) //超过购买限制
TicketMissData = New(2000103) //信息不完整
TicketSaleNotStart = New(2000104) //没开售
TicketSaleEnd = New(2000105) //已结束
TicketNoPriv = New(2000106) //无权操作
TicketInvalidUser = New(2000107) //无效用户
TicketPriceChanged = New(2000108) //价格变化
//销售-库存
TicketStockLack = New(2000201) //库存不足
TicketStockLogNotFound = New(2000202) //没有库存操作记录
TicketStockUpdateFail = New(2000203) //库存更新失败
//番剧推荐
SugEsSearchErr = New(2002000) //es搜索错误
SugSearchTypeErr = New(2002001) //搜索类型错误
SugOpTypeErr = New(2002002) //操作类型错误
SugOpErr = New(2002003) //add or del match fail
SugItemNone = New(2002004) //商品不存在
SugSeasonNone = New(2002005) //番剧不存在
//防刷工具
ParamInvalid = New(2001000) //参数错误
UpdateError = New(2001002) //更新失败
QusbNotFound = New(2001003) //找不到题库
QusIDInvalid = New(2001005) //题目id错误
BankUsing = New(2001007) //题目正在使用
BindBankNotFound = New(2001009) //未找到题库绑定关系
AnswerError = New(2001010) //答案错误
GetQusBankInfoCache = New(2001011) //获取题库缓存失败
GetComponentTimesErr = New(2001012) //获取组件缓存失败
SetComponentTimesErr = New(2001013) //设置答题次数缓存失败
SetComponentIDErr = New(2001014) //设置组件缓存失败
GetComponentIDErr = New(2001015) //获取组件ID缓存失败
SameCompentErr = New(2001016) //相同组件
GetQusIDsErr = New(2001017) //获取题目失败
AnswerPoiError = New(2001018) //答案错误
NotEnoughQuestion = New(2001019) //部分题库不足3题无法绑定请绑定别的题库或者修改题库
AntiSalesTimeErr = New(2001020) //售卖时间有错
AntiIPChangeLimit = New(2001021) //用户IP变更
AntiLimitNumUpper = New(2001022) //次数达到上限
AntiCheckVoucherErr = New(2001023) //用户凭证验证失败
AntiValidateFailed = New(2001024) //验证失败
AntiGeetestCountUpper = New(2001025) //极验总数达到上线
AntiCustomerErr = New(2001026) //业务方错误
AntiBlackErr = New(2001027) //黑名单用户
//项目
TicketCannotDelTk = New(2004000) //无法删除票价
TicketDelTkFailed = New(2004001) //删除票价失败
TicketLkTkNotFound = New(2004002) //关联票种不存在
TicketLkTkTypeNotFound = New(2004003) //关联票种类型不存在
TicketLkScNotFound = New(2004004) //关联场次不存在
TicketCannotDelSc = New(2004005) //无法删除场次
TicketLkScTimeNotFound = New(2004006) //关联的场次时间不存在
TicketPidIsEmpty = New(2004007) //项目id为空
TicketMainInfoTooLarge = New(2004008) //项目版本详情信息量过大
TicketDelTkExFailed = New(2004009) //删除票价额外信息失败
TicketAddVersionFailed = New(2004010) //添加版本信息失败
TicketAddVerExtFailed = New(2004011) //添加版本详情失败
TicketBannerIDEmpty = New(2004012) //BannerID为空
TicketVerCannotEdit = New(2004013) //版本不可编辑
TicketVerCannotReview = New(2004014) //无法审核 非待审核版本
TicketAddTagFailed = New(2004015) //添加项目标签失败
)

55
library/ecode/pb/BUILD Normal file
View File

@@ -0,0 +1,55 @@
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["ecode.go"],
embed = [":pb_go_proto"],
importpath = "go-common/library/ecode/pb",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/ecode:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
"@io_bazel_rules_go//proto/wkt:any_go_proto",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
proto_library(
name = "pb_proto",
srcs = ["ecode.proto"],
tags = ["automanaged"],
deps = ["@com_google_protobuf//:any_proto"],
)
go_proto_library(
name = "pb_go_proto",
compilers = ["@io_bazel_rules_go//proto:go_proto"],
importpath = "go-common/library/ecode/pb",
proto = ":pb_proto",
tags = ["automanaged"],
deps = ["@io_bazel_rules_go//proto/wkt:any_go_proto"],
)

48
library/ecode/pb/ecode.go Normal file
View File

@@ -0,0 +1,48 @@
package pb
import (
"strconv"
"go-common/library/ecode"
any "github.com/golang/protobuf/ptypes/any"
)
func (e *Error) Error() string {
return strconv.FormatInt(int64(e.GetErrCode()), 10)
}
// Code is the code of error.
func (e *Error) Code() int {
return int(e.GetErrCode())
}
// Message is error message.
func (e *Error) Message() string {
return e.GetErrMessage()
}
// Equal compare whether two errors are equal.
func (e *Error) Equal(ec error) bool {
return ecode.Cause(ec).Code() == e.Code()
}
// Details return error details.
func (e *Error) Details() []interface{} {
return []interface{}{e.GetErrDetail()}
}
// From will convert ecode.Codes to pb.Error.
//
// Deprecated: please use ecode.Error
func From(ec ecode.Codes) *Error {
var detail *any.Any
if details := ec.Details(); len(details) > 0 {
detail, _ = details[0].(*any.Any)
}
return &Error{
ErrCode: int32(ec.Code()),
ErrMessage: ec.Message(),
ErrDetail: detail,
}
}

View File

@@ -0,0 +1,96 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: error.proto
package pb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import any "github.com/golang/protobuf/ptypes/any"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Deprecated: please use ecode.Error
type Error struct {
ErrCode int32 `protobuf:"varint,1,opt,name=err_code,json=errCode,proto3" json:"err_code,omitempty"`
ErrMessage string `protobuf:"bytes,2,opt,name=err_message,json=errMessage,proto3" json:"err_message,omitempty"`
ErrDetail *any.Any `protobuf:"bytes,3,opt,name=err_detail,json=errDetail,proto3" json:"err_detail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Error) Reset() { *m = Error{} }
func (m *Error) String() string { return proto.CompactTextString(m) }
func (*Error) ProtoMessage() {}
func (*Error) Descriptor() ([]byte, []int) {
return fileDescriptor_error_28aad86a4e53115b, []int{0}
}
func (m *Error) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Error.Unmarshal(m, b)
}
func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Error.Marshal(b, m, deterministic)
}
func (dst *Error) XXX_Merge(src proto.Message) {
xxx_messageInfo_Error.Merge(dst, src)
}
func (m *Error) XXX_Size() int {
return xxx_messageInfo_Error.Size(m)
}
func (m *Error) XXX_DiscardUnknown() {
xxx_messageInfo_Error.DiscardUnknown(m)
}
var xxx_messageInfo_Error proto.InternalMessageInfo
func (m *Error) GetErrCode() int32 {
if m != nil {
return m.ErrCode
}
return 0
}
func (m *Error) GetErrMessage() string {
if m != nil {
return m.ErrMessage
}
return ""
}
func (m *Error) GetErrDetail() *any.Any {
if m != nil {
return m.ErrDetail
}
return nil
}
func init() {
proto.RegisterType((*Error)(nil), "err.Error")
}
func init() { proto.RegisterFile("error.proto", fileDescriptor_error_28aad86a4e53115b) }
var fileDescriptor_error_28aad86a4e53115b = []byte{
// 164 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x8d, 0xc1, 0xca, 0x82, 0x40,
0x14, 0x85, 0x99, 0x5f, 0xfc, 0xcb, 0x71, 0x37, 0xb4, 0xd0, 0x36, 0x49, 0x2b, 0x57, 0x23, 0xe4,
0x13, 0x44, 0xb5, 0x6c, 0xe3, 0x0b, 0x88, 0xe6, 0x49, 0x02, 0xf3, 0xc6, 0xd1, 0x20, 0xdf, 0x3e,
0x1c, 0x69, 0x79, 0xcf, 0xf7, 0x71, 0x3f, 0x1d, 0x82, 0x14, 0xda, 0x17, 0x65, 0x14, 0xe3, 0x81,
0xdc, 0xc6, 0xad, 0x48, 0xdb, 0x21, 0x73, 0x53, 0xfd, 0xbe, 0x67, 0x55, 0x3f, 0x2d, 0x7c, 0xff,
0xd1, 0xfe, 0x65, 0xd6, 0x4d, 0xac, 0xd7, 0x20, 0xcb, 0x9b, 0x34, 0x88, 0x54, 0xa2, 0x52, 0xbf,
0x58, 0x81, 0x3c, 0x49, 0x03, 0xb3, 0x73, 0x2f, 0xcb, 0x27, 0x86, 0xa1, 0x6a, 0x11, 0xfd, 0x25,
0x2a, 0x0d, 0x0a, 0x0d, 0xf2, 0xba, 0x2c, 0x26, 0xd7, 0xf3, 0x55, 0x36, 0x18, 0xab, 0x47, 0x17,
0x79, 0x89, 0x4a, 0xc3, 0xc3, 0xc6, 0x2e, 0x51, 0xfb, 0x8b, 0xda, 0x63, 0x3f, 0x15, 0x01, 0xc8,
0xb3, 0xd3, 0xea, 0x7f, 0x07, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x41, 0x22, 0xfd,
0xaf, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,13 @@
syntax = "proto3";
package pb;
import "google/protobuf/any.proto";
option go_package = "go-common/library/ecode/pb";
message Error {
int32 err_code = 1;
string err_message = 2;
google.protobuf.Any err_detail = 3;
}

103
library/ecode/status.go Normal file
View File

@@ -0,0 +1,103 @@
package ecode
import (
"fmt"
"strconv"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"go-common/library/ecode/internal/types"
)
// Error new status with code and message
func Error(code Code, message string) *Status {
return &Status{s: &types.Status{Code: int32(code.Code()), Message: message}}
}
// Errorf new status with code and message
func Errorf(code Code, format string, args ...interface{}) *Status {
return Error(code, fmt.Sprintf(format, args...))
}
var _ Codes = &Status{}
// Status statusError is an alias of a status proto
// implement ecode.Codes
type Status struct {
s *types.Status
}
// Error implement error
func (s *Status) Error() string {
return s.Message()
}
// Code return error code
func (s *Status) Code() int {
return int(s.s.Code)
}
// Message return error message for developer
func (s *Status) Message() string {
if s.s.Message == "" {
return strconv.Itoa(int(s.s.Code))
}
return s.s.Message
}
// Details return error details
func (s *Status) Details() []interface{} {
if s == nil || s.s == nil {
return nil
}
details := make([]interface{}, 0, len(s.s.Details))
for _, any := range s.s.Details {
detail := &ptypes.DynamicAny{}
if err := ptypes.UnmarshalAny(any, detail); err != nil {
details = append(details, err)
continue
}
details = append(details, detail.Message)
}
return details
}
// WithDetails WithDetails
func (s *Status) WithDetails(pbs ...proto.Message) (*Status, error) {
for _, pb := range pbs {
anyMsg, err := ptypes.MarshalAny(pb)
if err != nil {
return s, err
}
s.s.Details = append(s.s.Details, anyMsg)
}
return s, nil
}
// Equal for compatible.
// Deprecated: please use ecode.EqualError.
func (s *Status) Equal(err error) bool {
return EqualError(s, err)
}
// Proto return origin protobuf message
func (s *Status) Proto() *types.Status {
return s.s
}
// FromCode create status from ecode
func FromCode(code Code) *Status {
return &Status{s: &types.Status{Code: int32(code)}}
}
// FromProto new status from grpc detail
func FromProto(pbMsg proto.Message) Codes {
if msg, ok := pbMsg.(*types.Status); ok {
if msg.Message == "" {
// NOTE: if message is empty convert to pure Code, will get message from config center.
return Code(msg.Code)
}
return &Status{s: msg}
}
return Errorf(ServerErr, "invalid proto message get %v", pbMsg)
}

View File

@@ -0,0 +1,66 @@
package ecode
import (
"testing"
"time"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/smartystreets/goconvey/convey"
"github.com/stretchr/testify/assert"
"go-common/library/ecode/internal/types"
)
func TestEqual(t *testing.T) {
convey.Convey("Equal", t, func(ctx convey.C) {
ctx.Convey("When err1=Error(RequestErr, 'test') and err2=Errorf(RequestErr, 'test')", func(ctx convey.C) {
err1 := Error(RequestErr, "test")
err2 := Errorf(RequestErr, "test")
ctx.Convey("Then err1=err2, err1 != nil", func(ctx convey.C) {
ctx.So(err1, convey.ShouldResemble, err2)
ctx.So(err1, convey.ShouldNotBeNil)
})
})
})
// assert.True(t, OK.Equal(nil))
// assert.True(t, err1.Equal(err2))
// assert.False(t, err1.Equal(nil))
// assert.True(t, Equal(nil, nil))
}
func TestDetail(t *testing.T) {
m := &timestamp.Timestamp{Seconds: time.Now().Unix()}
st, _ := Error(RequestErr, "RequestErr").WithDetails(m)
assert.Equal(t, "RequestErr", st.Message())
assert.Equal(t, int(RequestErr), st.Code())
assert.IsType(t, m, st.Details()[0])
}
func TestFromCode(t *testing.T) {
err := FromCode(RequestErr)
assert.Equal(t, int(RequestErr), err.Code())
assert.Equal(t, "-400", err.Message())
}
func TestFromProto(t *testing.T) {
msg := &types.Status{Code: 2233, Message: "error"}
err := FromProto(msg)
assert.Equal(t, 2233, err.Code())
assert.Equal(t, "error", err.Message())
m := &timestamp.Timestamp{Seconds: time.Now().Unix()}
err = FromProto(m)
assert.Equal(t, -500, err.Code())
assert.Contains(t, err.Message(), "invalid proto message get")
}
func TestEmpty(t *testing.T) {
st := &Status{}
assert.Len(t, st.Details(), 0)
st = nil
assert.Len(t, st.Details(), 0)
}

56
library/ecode/tip/BUILD Normal file
View File

@@ -0,0 +1,56 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["tip_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = ["//library/ecode:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["tip.go"],
importpath = "go-common/library/ecode/tip",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/time:go_default_library",
],
)
go_test(
name = "go_default_xtest",
srcs = ["example_test.go"],
tags = ["automanaged"],
deps = [
"//library/ecode/tip:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/netutil/breaker:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,20 @@
### ecode sdk
##### Version 2.3.0
> 1. 从bussiness 移动到ecode&& ecode/tips
##### Version 2.2.1
> 1. 删除Config里面App配置
##### Version 2.2.0
> 1.规范不同部门错误码分段并将主站错误码从common里拆出来
##### Version 2.1.0
> 1. 使用新的ecode接口去平台化
##### Version 2.0.0
> 1. 通过接口获取所有错误信息,支持全量更新和增量更新,更新时间可分别配置
> 2. 支持错误发生的堆栈信息记录,通过日志还原堆栈
##### Version 1.0.0
> 1. 通过数据库读取全量错误信息每5分钟更新一次

View File

@@ -0,0 +1,11 @@
# Owner
all
# Author
zhoujixiang
chenshangqiang
# Reviewer
maojian
lintanghui
chenzhihui

12
library/ecode/tip/OWNERS Normal file
View File

@@ -0,0 +1,12 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- anyone
options:
no_parent_owners: true
reviewers:
- chenshangqiang
- chenzhihui
- lintanghui
- maojian
- zhoujixiang

View File

@@ -0,0 +1,23 @@
# go-common/business/ecode
##### 项目简介
> 1. 提供所有请求的错误码及其错误信息管理,错误信息在管理平台配置,支持自动更新
> 2. 提供错误使用规范及文档,包含堆栈信息使用
##### 编译环境
> 1. 请只用golang v1.7.x以上版本编译执行。
##### 依赖包
> 1. 依赖github.com/pkg/errors当前版本v0.8.0
##### 编译执行
> 1. 启动执行 ecode.Init(conf.Conf.Ecode)初始化ecode 配置
> 2. 配置参考 http://info.bilibili.co/pages/viewpage.action?pageId=3684076 配置
##### 测试
> 1. 执行当前目录下所有测试文件,测试所有功能
##### 特别说明
> 1. common.go 里面保存所有业务的code码当有新增加code码需求时请记得一定及时更新common,并在管理平台配置对应信息
> 2. 管理平台地址 http://apm-monitor.bilibili.co/#/codes/codeslist?name=all
> 3. 按部门给错误码分大段部门内部按业务模块继续分段具体参考info地址: http://info.bilibili.co/pages/viewpage.action?pageId=5374316

View File

@@ -0,0 +1,34 @@
package tip_test
import (
"time"
"go-common/library/ecode/tip"
xhttp "go-common/library/net/http/blademaster"
"go-common/library/net/netutil/breaker"
xtime "go-common/library/time"
)
func ExampleInit() {
conf := &tip.Config{
Domain: "172.16.33.248:6401",
Diff: xtime.Duration(5 * time.Minute),
ClientConfig: &xhttp.ClientConfig{
App: &xhttp.App{
Key: "test",
Secret: "e6c4c252dc7e3d8a90805eecd7c73396",
},
Dial: xtime.Duration(time.Millisecond * 100),
Timeout: xtime.Duration(time.Second * 2),
KeepAlive: xtime.Duration(time.Second * 2),
Breaker: &breaker.Config{
Window: xtime.Duration(time.Millisecond * 10),
Sleep: xtime.Duration(time.Second * 10),
Bucket: 10,
Ratio: 0.5,
Request: 100,
},
},
}
tip.Init(conf)
}

175
library/ecode/tip/tip.go Normal file
View File

@@ -0,0 +1,175 @@
package tip
import (
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"net/url"
"strconv"
"sync/atomic"
"time"
cmcd "go-common/library/ecode"
"go-common/library/log"
xhttp "go-common/library/net/http/blademaster"
xtime "go-common/library/time"
)
const (
_codeOk = 0
_codeNotModified = -304
_checkURL = "http://%s/x/v1/msm/codes/2"
)
var (
defualtEcodes = &ecodes{}
defaultConfig = &Config{
Domain: "api.bilibili.co",
All: xtime.Duration(time.Hour),
Diff: xtime.Duration(time.Minute * 5),
ClientConfig: &xhttp.ClientConfig{
App: &xhttp.App{
Key: "3c4e41f926e51656",
Secret: "26a2095b60c24154521d24ae62b885bb",
},
Dial: xtime.Duration(time.Second),
Timeout: xtime.Duration(time.Second),
},
}
)
// Config config.
type Config struct {
// Domain server domain
Domain string
// All get all time slice
All xtime.Duration
// Diff get diff time slice
Diff xtime.Duration
//HTTPClient httpclient config
ClientConfig *xhttp.ClientConfig
}
type ecodes struct {
codes atomic.Value
client *xhttp.Client
conf *Config
}
type res struct {
Code int `json:"code"`
Message string `json:"message"`
Data *data `json:"data"`
}
type data struct {
Ver int64
MD5 string
Code map[int]string
}
// Init init ecode.
func Init(conf *Config) {
if conf == nil {
conf = defaultConfig
} else {
panic(`请删除配置文件内无用配置perf、log、trace、report、ecode、httpServer
http://info.bilibili.co/pages/viewpage.action?pageId=3671762
`)
}
defualtEcodes.conf = conf
defualtEcodes.client = xhttp.NewClient(conf.ClientConfig)
defualtEcodes.codes.Store(make(map[int]string))
ver, _ := defualtEcodes.update(0)
go defualtEcodes.updateproc(ver)
}
func (e *ecodes) updateproc(lastVer int64) {
var (
ver int64
err error
last = time.Now()
all = time.Duration(e.conf.All)
diff = time.Duration(e.conf.Diff)
)
if e.conf.All == 0 {
all = time.Hour
}
if e.conf.Diff == 0 {
diff = 5 * time.Minute
}
time.Sleep(diff)
for {
cur := time.Now()
if cur.Sub(last) > all {
if ver, err = e.update(0); err != nil {
log.Error("e.update() error(%v)", err)
time.Sleep(10 * time.Second)
continue
}
last = cur
} else {
if ver, err = e.update(lastVer); err != nil {
log.Error("e.update(%d) error(%v)", lastVer, err)
time.Sleep(10 * time.Second)
continue
}
}
lastVer = ver
time.Sleep(diff)
}
}
func (e *ecodes) update(ver int64) (lver int64, err error) {
var (
res = &res{}
bytes []byte
params = url.Values{}
)
params.Set("ver", strconv.FormatInt(ver, 10))
if err = e.client.Get(context.TODO(), fmt.Sprintf(_checkURL, e.conf.Domain), "", params, &res); err != nil {
err = fmt.Errorf("e.client.Get(%v) error(%v)", fmt.Sprintf(_checkURL, e.conf.Domain), err)
return
}
switch res.Code {
case _codeOk:
if res.Data == nil {
err = fmt.Errorf("code get() response error result: %v", res)
return
}
case _codeNotModified:
return ver, nil
default:
err = cmcd.Int(res.Code)
return
}
if bytes, err = json.Marshal(res.Data.Code); err != nil {
return
}
mb := md5.Sum(bytes)
if res.Data.MD5 != hex.EncodeToString(mb[:]) {
err = fmt.Errorf("get codes fail,error md5")
return
}
oCodes, ok := e.codes.Load().(map[int]string)
if !ok {
return
}
nCodes := copy(oCodes)
for k, v := range res.Data.Code {
nCodes[k] = v
}
cmcd.Register(nCodes)
e.codes.Store(nCodes)
return res.Data.Ver, nil
}
func copy(src map[int]string) (dst map[int]string) {
dst = make(map[int]string)
for k1, v1 := range src {
dst[k1] = v1
}
return
}

View File

@@ -0,0 +1,49 @@
package tip
import (
"sync"
"testing"
"go-common/library/ecode"
)
var (
once sync.Once
)
func initEcodes() {
once.Do(func() {
Init(nil)
})
}
func TestInit(t *testing.T) {
initEcodes()
testCodes(t)
}
func BenchmarkLookup(b *testing.B) {
initEcodes()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
b.Logf("Ecodes: lookup ServerErr: %s", ecode.ServerErr.Message())
b.Logf("Ecodes: lookup ServerErr: %s", ecode.NotModified.Message())
}
})
}
func testCodes(t *testing.T) {
if ver, err := defualtEcodes.update(1499843315); err != nil {
t.Logf("codes(%v)", err)
t.FailNow()
} else {
t.Logf("ver(%d)", ver)
}
if codes, ok := defualtEcodes.codes.Load().(map[int]string); !ok {
t.Errorf("codes load not ok")
t.FailNow()
} else {
t.Logf("%v", codes)
}
}