package rpc import ( "context" "encoding/json" "fmt" "log/slog" "nhooyr.io/websocket" ) func (s *server) handleRequest(ctx context.Context, c *websocket.Conn, data []byte) { var request Request err := json.Unmarshal(data, &request) if err != nil { respondError(ctx, c, "", ERROR_JRPC2_PARSE_ERROR, fmt.Errorf("Error Parsing Request: %w", err), nil) slog.ErrorContext(ctx, "Parsing Request", "err", err) return } // Get the Requested function fun, ok := s.methods[request.Method] if !ok { respondError(ctx, c, request.ID, ERROR_JRPC2_METHOD_NOT_FOUND, fmt.Errorf("Method Not Found"), nil) slog.ErrorContext(ctx, "Method Not Found") return } reqCtx, cancel := context.WithCancel(ctx) defer cancel() // Run the Requested function result, err := fun(reqCtx, request) if err != nil { respondError(ctx, c, request.ID, 1000, fmt.Errorf("Method Error: %w", err), result) slog.ErrorContext(ctx, "Method Error", "err", err) return } var rData json.RawMessage if data != nil { rData, err = json.Marshal(result) if err != nil { respondError(ctx, c, request.ID, ERROR_JRPC2_INTERNAL, fmt.Errorf("Error Marshalling Response Data: %w", err), nil) slog.ErrorContext(ctx, "Marshalling Response Data", "err", err) return } } else { rData = []byte("\"\"") } slog.InfoContext(ctx, "response data", "rdata", rData) resp, err := json.Marshal(Response{ ID: request.ID, Result: &rData, }) if err != nil { respondError(ctx, c, request.ID, ERROR_JRPC2_INTERNAL, fmt.Errorf("Error Marshalling Response: %w", err), nil) slog.ErrorContext(ctx, "Marshalling Response", "err", err) return } err = c.Write(ctx, websocket.MessageText, resp) if err != nil { respondError(ctx, c, request.ID, ERROR_JRPC2_INTERNAL, fmt.Errorf("Error Sending Response: %w", err), nil) slog.ErrorContext(ctx, "Sending Response", "err", err) return } }