The daemon RPC server was crashing with a nil pointer dereference when the global daemon received list, ready, stats, or other storage-dependent RPC requests. The global daemon is created with nil storage, causing these operations to panic when they attempted to access storage methods. This fix adds defensive nil checks at the beginning of all RPC handlers that require storage access. When storage is unavailable, they now return a proper JSON error response instead of crashing the daemon. The error message also informs users that the global daemon is deprecated and they should use local daemons instead. Handlers fixed: - handleCreate, handleUpdate, handleClose - handleList, handleShow, handleReady, handleStale - handleResolveID, handleStats, handleEpicStatus - handleCompact, handleCompactStats - handleDepAdd (and via handleSimpleStoreOp for all label/dep/comment ops) Co-authored-by: Test User <test@example.com>
This commit is contained in:
@@ -19,6 +19,12 @@ func (s *Server) handleCompact(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
sqliteStore, ok := store.(*sqlite.SQLiteStorage)
|
||||
if !ok {
|
||||
@@ -228,6 +234,12 @@ func (s *Server) handleCompactStats(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
sqliteStore, ok := store.(*sqlite.SQLiteStorage)
|
||||
if !ok {
|
||||
|
||||
@@ -87,6 +87,12 @@ func (s *Server) handleCreate(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
ctx := s.reqCtx(req)
|
||||
|
||||
// If parent is specified, generate child ID
|
||||
@@ -242,6 +248,12 @@ func (s *Server) handleUpdate(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
updates := updatesFromArgs(updateArgs)
|
||||
@@ -284,6 +296,12 @@ func (s *Server) handleClose(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
if err := store.CloseIssue(ctx, closeArgs.ID, closeArgs.Reason, s.reqActor(req)); err != nil {
|
||||
@@ -314,6 +332,12 @@ func (s *Server) handleList(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
filter := types.IssueFilter{
|
||||
Limit: listArgs.Limit,
|
||||
@@ -492,6 +516,13 @@ func (s *Server) handleResolveID(req *Request) Response {
|
||||
}
|
||||
}
|
||||
|
||||
if s.storage == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
resolvedID, err := utils.ResolvePartialID(ctx, s.storage, args.ID)
|
||||
if err != nil {
|
||||
@@ -518,6 +549,12 @@ func (s *Server) handleShow(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
issue, err := store.GetIssue(ctx, showArgs.ID)
|
||||
@@ -593,6 +630,12 @@ func (s *Server) handleReady(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
wf := types.WorkFilter{
|
||||
Status: types.StatusOpen,
|
||||
@@ -632,6 +675,12 @@ func (s *Server) handleStale(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
filter := types.StaleFilter{
|
||||
Days: staleArgs.Days,
|
||||
@@ -657,6 +706,12 @@ func (s *Server) handleStale(req *Request) Response {
|
||||
|
||||
func (s *Server) handleStats(req *Request) Response {
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
stats, err := store.GetStatistics(ctx)
|
||||
@@ -684,6 +739,12 @@ func (s *Server) handleEpicStatus(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
epics, err := store.GetEpicsEligibleForClosure(ctx)
|
||||
|
||||
@@ -19,6 +19,12 @@ func (s *Server) handleDepAdd(req *Request) Response {
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
dep := &types.Dependency{
|
||||
IssueID: depArgs.FromID,
|
||||
@@ -51,6 +57,12 @@ func (s *Server) handleSimpleStoreOp(req *Request, argsPtr interface{}, argDesc
|
||||
}
|
||||
|
||||
store := s.storage
|
||||
if store == nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: "storage not available (global daemon deprecated - use local daemon instead with 'bd daemon' in your project)",
|
||||
}
|
||||
}
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
if err := opFunc(ctx, store, s.reqActor(req)); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user