完整启动示例可能因依赖失败而 panic,也会丢弃服务器启动错误
原文依据:5 处指南说明 `MustInvoke` 遇错会 panic,但完整 `main` 示例在组合根使用它;这里没有外层 `Invoke` 将 panic 转回错误。示例还在 goroutine 中调用 `ListenAndServe` 并忽略返回值。
提供者初始化失败会直接终止进程;端口占用或监听失败则可能留下仍在等待信号、却没有提供 HTTP 服务的进程,影响可用性和故障检测。
指南明确说 `MustInvoke` 出错会 panic,只有在提供者内部、由外层 `Invoke` 捕获时才安全;但完整 `main` 示例直接在组合根调用 `MustInvoke`,因此初始化失败可终止进程。示例还在 goroutine 中丢弃 `ListenAndServe` 的错误,端口占用或监听失败时程序仍可能等待关闭信号而没有提供服务。用户可要求显式处理解析和服务器启动错误。
// (e.g. an HTTP handler that must degrade gracefully instead of crashing)db, err := do.Invoke[Database](injector)// MustInvoke panics on error — preferred in providers, recovered by do.Invoke on the parent calldb := do.MustInvoke[Database](injector)```查看另外 4 个位置
server := do.MustInvoke[*http.Server](injector) go server.ListenAndServe() _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt)}| -------------------------- | ----------------------------------------- || `do.Invoke[T]()` | Get service (with error) || `do.InvokeNamed[T]()` | Get named service || `do.InvokeAs[T]()` | Get first service matching interface || `do.InvokeStruct[T]()` | Inject into struct fields using tags || `do.MustInvoke[T]()` | Get service (panic on error) || `do.MustInvokeNamed[T]()` | Get named service (panic on error) |```go// Invoke with error handling — reserve for call sites outside the DI graph// (e.g. an HTTP handler that must degrade gracefully instead of crashing)db, err := do.Invoke[Database](injector)// MustInvoke panics on error — preferred in providers, recovered by do.Invoke on the parent calldb := do.MustInvoke[Database](injector)```Inside a provider function, always use `do.MustInvoke` (or `MustInvokeAs`/`MustInvokeNamed`/`MustInvokeStruct`) rather than the error-returning variant:- A provider already returns `(T, error)`, so propagating a dependency failure with `do.Invoke` costs an extra `if err != nil { return nil, err }` on every call.- `do.MustInvoke` panics instead, but samber/do correctly catches and recovers that panic at the enclosing `Invoke` call and converts it back into a regular error — this recover happens inside the library itself, not in caller code, so `MustInvoke` is safe to use inside providers.- The failure still surfaces as an error at the composition root, just without the manual boilerplate in every provider.## Full Application Setup```gofunc main() { injector := do.New( infrastructure.Package, repository.Package, service.Package, transport.Package, ) server := do.MustInvoke[*http.Server](injector) go server.ListenAndServe() _ = injector.ShutdownOnSignalsWithContext(context.Background(), os.Interrupt)}```