feat(redis): 具名化 JS 导出并动态包裹错误(by AI)
This commit is contained in:
parent
f5ba9b2f97
commit
701284368b
@ -1,5 +1,9 @@
|
|||||||
# CHANGELOG - redis
|
# CHANGELOG - redis
|
||||||
|
|
||||||
|
## v1.5.6 (2026-06-21)
|
||||||
|
- **JS 对齐**: 重构 JS 导出为具名函数,并引入 `jsmod.MakeError` 动态包装错误以获取调用栈。
|
||||||
|
- **依赖更新**: 升级依赖 `jsmod` 至 `v1.5.3`,`cast` 至 `v1.5.3`,`rand` 至 `v1.5.3`,`encoding` 至 `v1.5.4`,`shell` 至 `v1.5.3`,`safe` 至 `v1.5.2`,`id` 至 `v1.5.4`,`crypto` 至 `v1.5.3`,`file` 至 `v1.5.5`,`config` 至 `v1.5.3`,`log` 至 `v1.5.8`。
|
||||||
|
|
||||||
## v1.5.5 (2026-06-20)
|
## v1.5.5 (2026-06-20)
|
||||||
- **JS 导出重构**:
|
- **JS 导出重构**:
|
||||||
- 移除 `js_export.go` 中冗余的独立命令快捷函数(SET, GET, DEL, EXISTS, EXPIRE, PUBLISH),统一通过 `Do` 方法调用。
|
- 移除 `js_export.go` 中冗余的独立命令快捷函数(SET, GET, DEL, EXISTS, EXPIRE, PUBLISH),统一通过 `Do` 方法调用。
|
||||||
|
|||||||
6
TEST.md
6
TEST.md
@ -16,5 +16,9 @@
|
|||||||
- **BenchmarkGetSet**: ~80,000 ns/op (Simple GET/SET loop)
|
- **BenchmarkGetSet**: ~80,000 ns/op (Simple GET/SET loop)
|
||||||
- **BenchmarkIDMaker**: ~2,300 ns/op (High-performance sequence generation)
|
- **BenchmarkIDMaker**: ~2,300 ns/op (High-performance sequence generation)
|
||||||
|
|
||||||
> Date: 2026-05-05
|
## 🛡️ 鲁棒性防御 (Robustness)
|
||||||
|
- **安全沙箱拦截**:在 `SafeMode` 下,仅允许 GET/EXISTS/ZRANGE 等读操作命令,自动拦截所有写操作命令并返回错误。
|
||||||
|
- **JS 错误调用栈**:JS 桥接层改用具名导出并使用 `jsmod.MakeError` 包裹错误(包括 Do 返回的 Result.Error 字段),确保 JS 抛出异常时携带准确的 Go 运行时堆栈。
|
||||||
|
|
||||||
|
> Date: 2026-06-21
|
||||||
> Environment: Darwin / Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
|
> Environment: Darwin / Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
|
||||||
|
|||||||
22
go.mod
22
go.mod
@ -3,21 +3,21 @@ module apigo.cc/go/redis
|
|||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
apigo.cc/go/cast v1.5.2
|
apigo.cc/go/cast v1.5.3
|
||||||
apigo.cc/go/config v1.5.2
|
apigo.cc/go/config v1.5.3
|
||||||
apigo.cc/go/crypto v1.5.2
|
apigo.cc/go/crypto v1.5.3
|
||||||
apigo.cc/go/encoding v1.5.3
|
apigo.cc/go/encoding v1.5.4
|
||||||
apigo.cc/go/id v1.5.3
|
apigo.cc/go/id v1.5.4
|
||||||
apigo.cc/go/jsmod v1.5.2
|
apigo.cc/go/jsmod v1.5.3
|
||||||
apigo.cc/go/log v1.5.6
|
apigo.cc/go/log v1.5.8
|
||||||
apigo.cc/go/safe v1.5.1
|
apigo.cc/go/safe v1.5.2
|
||||||
github.com/gomodule/redigo v2.0.0+incompatible
|
github.com/gomodule/redigo v2.0.0+incompatible
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
apigo.cc/go/file v1.5.4 // indirect
|
apigo.cc/go/file v1.5.5 // indirect
|
||||||
apigo.cc/go/rand v1.5.2 // indirect
|
apigo.cc/go/rand v1.5.3 // indirect
|
||||||
apigo.cc/go/shell v1.5.2 // indirect
|
apigo.cc/go/shell v1.5.3 // indirect
|
||||||
golang.org/x/crypto v0.52.0 // indirect
|
golang.org/x/crypto v0.52.0 // indirect
|
||||||
golang.org/x/sys v0.45.0 // indirect
|
golang.org/x/sys v0.45.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
|||||||
40
js_export.go
40
js_export.go
@ -13,36 +13,44 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
jsmod.Register("redis", map[string]any{
|
jsmod.Register("redis", map[string]any{
|
||||||
// 入口:支持别名获取,不传则默认 "default"
|
// 入口:支持别名获取,不传则默认 "default"
|
||||||
"Get": func(ctx context.Context, name *string) (*jsRedis, error) {
|
"Get": jsGet,
|
||||||
|
|
||||||
|
// 默认快捷调用 (面向 "default" 实例)
|
||||||
|
"Do": jsDo,
|
||||||
|
"MakeID": jsMakeID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func jsGet(ctx context.Context, name *string) (*jsRedis, error) {
|
||||||
target := "default"
|
target := "default"
|
||||||
if name != nil {
|
if name != nil {
|
||||||
target = *name
|
target = *name
|
||||||
}
|
}
|
||||||
rd := GetRedis(target, nil)
|
rd := GetRedis(target, nil)
|
||||||
if rd.Error != nil {
|
if rd.Error != nil {
|
||||||
return nil, rd.Error
|
return nil, jsmod.MakeError(rd.Error)
|
||||||
}
|
}
|
||||||
return &jsRedis{rd: rd, ctx: ctx}, nil
|
return &jsRedis{rd: rd, ctx: ctx}, nil
|
||||||
},
|
}
|
||||||
|
|
||||||
// 默认快捷调用 (面向 "default" 实例)
|
func jsDo(ctx context.Context, cmd string, args ...any) (*Result, error) {
|
||||||
"Do": func(ctx context.Context, cmd string, args ...any) (*Result, error) {
|
|
||||||
jr := getDefaultRedisForJS(ctx)
|
jr := getDefaultRedisForJS(ctx)
|
||||||
if jr.rd.Error != nil {
|
if jr.rd.Error != nil {
|
||||||
return nil, jr.rd.Error
|
return nil, jsmod.MakeError(jr.rd.Error)
|
||||||
}
|
}
|
||||||
res := jr.Do(cmd, args...)
|
res := jr.Do(cmd, args...)
|
||||||
return res, res.Error
|
if res != nil && res.Error != nil {
|
||||||
},
|
return res, jsmod.MakeError(res.Error)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
"MakeID": func(ctx context.Context, size int, forDB *string) string {
|
func jsMakeID(ctx context.Context, size int, forDB *string) string {
|
||||||
jr := getDefaultRedisForJS(ctx)
|
jr := getDefaultRedisForJS(ctx)
|
||||||
if jr.rd.Error != nil {
|
if jr.rd.Error != nil {
|
||||||
return id.MakeID(size)
|
return id.MakeID(size)
|
||||||
}
|
}
|
||||||
return jr.MakeID(size, forDB)
|
return jr.MakeID(size, forDB)
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsRedis struct {
|
type jsRedis struct {
|
||||||
@ -86,9 +94,15 @@ func (jr *jsRedis) checkSafe(cmd string) error {
|
|||||||
|
|
||||||
func (jr *jsRedis) Do(cmd string, args ...any) *Result {
|
func (jr *jsRedis) Do(cmd string, args ...any) *Result {
|
||||||
if err := jr.checkSafe(cmd); err != nil {
|
if err := jr.checkSafe(cmd); err != nil {
|
||||||
return &Result{Error: err}
|
return &Result{Error: jsmod.MakeError(err)}
|
||||||
}
|
}
|
||||||
return jr.rd.Do(cmd, args...)
|
res := jr.rd.Do(cmd, args...)
|
||||||
|
if res != nil && res.Error != nil {
|
||||||
|
resCopy := *res
|
||||||
|
resCopy.Error = jsmod.MakeError(res.Error)
|
||||||
|
return &resCopy
|
||||||
|
}
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID Generation
|
// ID Generation
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user