morffix/rpc/request.go

69 lines
1.8 KiB
Go

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
}
}