feat: 添加 WithStreamErrors 查询流式调用执行过程中的异常
流式输出/双向流的 handler(Python 生成器)如果执行过程中抛异常, Invoke[chan T] 本身的 err 只描述"调用有没有发起成功",跟这个异常 无关(永远是 nil),channel 只会静默提前关闭,调用方原本完全无法 感知。新增 WithStreamErrors(ctx) 返回一个包过的 ctx 和一个查询函数 streamErr,opt-in 之后可以查到具体错误。 错误记录挂在 WithStreamErrors 返回的 ctx 的对象图里(context.WithValue), 不是全局表——调用方不再引用 ctx/channel 时会被 GC 自然回收,不需要 任何显式清理逻辑,也不依赖 ctx.Done(),即使用 context.Background() 也能正常释放;ctx 之后被别的 context.With*(包括 StickyCtx)再包一层 也不影响查询。 同时补充完整的自动化测试覆盖 example/main.go 里演示过的所有功能: 四种调用模式 × int/struct/slice/[]byte 的组合(client_test.go)、 WithHandlers/call_go 全双工(handlers_test.go)、NewSession 隔离性 与 StickyCtx 路由(session_test.go),之前这些只能靠人肉跑 go run 看输出,现在都有真实断言。
This commit is contained in:
@@ -336,6 +336,28 @@ func demoTimeout(script string) {
|
||||
fmt.Print(" ", v)
|
||||
}
|
||||
fmt.Println() // 应该完整输出 1~9,不会被 500ms 默认超时打断
|
||||
|
||||
// ── 示例5:WithStreamErrors——流式 handler 执行过程中抛异常,channel 会静默
|
||||
// 提前关闭,Invoke 本身的 err 只描述"调用有没有发起成功",跟这个异常无关
|
||||
// (永远是 nil)。想知道流是不是因为 Python 侧异常提前结束,需要先用
|
||||
// WithStreamErrors 包一层 ctx(opt-in),拿到的 streamErr 函数不用再传 ctx。
|
||||
//
|
||||
// 错误记录挂在 WithStreamErrors 返回的这个 ctx 的对象图里,调用方不再引用
|
||||
// ctx5/ch3 时会被 GC 自然回收,不需要任何显式清理,即使用 context.Background()
|
||||
// 也一样能正常释放(不依赖 ctx.Done())。
|
||||
ctx5, streamErr := gobridge.WithStreamErrors(context.Background())
|
||||
ch3, err := gobridge.Invoke[chan int](ctx5, pool, "stream_then_raise", 3)
|
||||
if err != nil {
|
||||
log.Fatal(err) // 这里的 err 只可能是"发起调用失败",不会是 stream_then_raise 里的异常
|
||||
}
|
||||
fmt.Print("stream_then_raise(3)(执行过程中会抛异常)=")
|
||||
for v := range ch3 {
|
||||
fmt.Print(" ", v)
|
||||
}
|
||||
fmt.Println()
|
||||
if err := streamErr(ch3); err != nil {
|
||||
fmt.Println("streamErr 查到执行过程中的异常:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func demoBlocking(script string) {
|
||||
|
||||
Reference in New Issue
Block a user