Handle error conditions better and detect support methods automatically

This commit is contained in:
tutman96 2025-01-06 18:11:51 +00:00
parent e61decfb33
commit 2428c15f88
5 changed files with 31 additions and 21 deletions

View File

@ -53,8 +53,10 @@ func (p *PluginInstall) GetStatus() (*PluginStatus, error) {
Enabled: p.Enabled, Enabled: p.Enabled,
} }
if p.rpcServer != nil && p.rpcServer.status.Status != "disconnected" { // If the rpc server is connected and the plugin is reporting status, use that
log.Printf("Status from RPC: %v", p.rpcServer.status) if p.rpcServer != nil &&
p.rpcServer.status.Status != "disconnected" &&
p.rpcServer.status.Status != "unknown" {
status.Status = p.rpcServer.status.Status status.Status = p.rpcServer.status.Status
status.Message = p.rpcServer.status.Message status.Message = p.rpcServer.status.Message
@ -66,7 +68,7 @@ func (p *PluginInstall) GetStatus() (*PluginStatus, error) {
if p.processManager != nil { if p.processManager != nil {
status.Status = "running" status.Status = "running"
if p.processManager.LastError != nil { if p.processManager.LastError != nil {
status.Status = "errored" status.Status = "error"
status.Message = p.processManager.LastError.Error() status.Message = p.processManager.LastError.Error()
} }
} }

View File

@ -9,6 +9,7 @@ import (
"net" "net"
"os" "os"
"path" "path"
"slices"
"time" "time"
) )
@ -19,12 +20,17 @@ type PluginRpcStatus struct {
var ( var (
PluginRpcStatusDisconnected = PluginRpcStatus{"disconnected", ""} PluginRpcStatusDisconnected = PluginRpcStatus{"disconnected", ""}
PluginRpcStatusUnknown = PluginRpcStatus{"unknown", ""}
PluginRpcStatusLoading = PluginRpcStatus{"loading", ""} PluginRpcStatusLoading = PluginRpcStatus{"loading", ""}
PluginRpcStatusPendingConfiguration = PluginRpcStatus{"pending-configuration", ""} PluginRpcStatusPendingConfiguration = PluginRpcStatus{"pending-configuration", ""}
PluginRpcStatusRunning = PluginRpcStatus{"running", ""} PluginRpcStatusRunning = PluginRpcStatus{"running", ""}
PluginRpcStatusError = PluginRpcStatus{"error", ""} PluginRpcStatusError = PluginRpcStatus{"error", ""}
) )
type PluginRpcSupportedMethods struct {
SupportedRpcMethods []string `json:"supported_rpc_methods"`
}
type PluginRpcServer struct { type PluginRpcServer struct {
install *PluginInstall install *PluginInstall
workingDir string workingDir string
@ -103,10 +109,10 @@ func (s *PluginRpcServer) handleConnection(conn net.Conn) {
// TODO: if read 65k bytes, then likey there is more data to read... figure out how to handle this // TODO: if read 65k bytes, then likey there is more data to read... figure out how to handle this
n, err := conn.Read(buf) n, err := conn.Read(buf)
if err != nil { if err != nil {
log.Printf("Failed to read message: %v", err)
if errors.Is(err, net.ErrClosed) { if errors.Is(err, net.ErrClosed) {
s.status = PluginRpcStatusDisconnected s.status = PluginRpcStatusDisconnected
} else { } else {
log.Printf("Failed to read message: %v", err)
s.status = PluginRpcStatusError s.status = PluginRpcStatusError
s.status.Message = fmt.Errorf("failed to read message: %v", err).Error() s.status.Message = fmt.Errorf("failed to read message: %v", err).Error()
} }
@ -124,21 +130,23 @@ func (s *PluginRpcServer) handleConnection(conn net.Conn) {
} }
func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrpc.JSONRPCServer) { func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrpc.JSONRPCServer) {
// log.Printf("Plugin rpc server started. Getting supported methods...") s.status = PluginRpcStatusUnknown
// supportedMethodsResponse, err := rpcserver.Request("getPluginSupportedMethods", map[string]interface{}{})
// if err != nil {
// log.Printf("Failed to get supported methods: %v", err)
// s.status = PluginRpcStatusError
// s.status.Message = fmt.Errorf("error getting supported methods: %v", err).Error()
// }
// if supportedMethodsResponse.Error != nil { log.Printf("Plugin rpc server started. Getting supported methods...")
// log.Printf("Failed to get supported methods: %v", supportedMethodsResponse.Error) var supportedMethodsResponse PluginRpcSupportedMethods
// s.status = PluginRpcStatusError err := rpcserver.Request("getPluginSupportedMethods", nil, &supportedMethodsResponse)
// s.status.Message = fmt.Errorf("error getting supported methods: %v", supportedMethodsResponse.Error).Error() if err != nil {
// } log.Printf("Failed to get supported methods: %v", err)
s.status = PluginRpcStatusError
s.status.Message = fmt.Errorf("error getting supported methods: %v", err.Message).Error()
}
// log.Printf("Plugin has supported methods: %v", supportedMethodsResponse.Result) log.Printf("Plugin has supported methods: %v", supportedMethodsResponse.SupportedRpcMethods)
if !slices.Contains(supportedMethodsResponse.SupportedRpcMethods, "getPluginStatus") {
log.Printf("Plugin does not support getPluginStatus method")
return
}
ticker := time.NewTicker(1 * time.Second) ticker := time.NewTicker(1 * time.Second)
for { for {
@ -147,7 +155,7 @@ func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrp
return return
case <-ticker.C: case <-ticker.C:
var statusResponse PluginRpcStatus var statusResponse PluginRpcStatus
err := rpcserver.Request("getPluginStatus", map[string]interface{}{}, &statusResponse) err := rpcserver.Request("getPluginStatus", nil, &statusResponse)
if err != nil { if err != nil {
log.Printf("Failed to get status: %v", err) log.Printf("Failed to get status: %v", err)
if err, ok := err.Data.(error); ok && errors.Is(err, net.ErrClosed) { if err, ok := err.Data.(error); ok && errors.Is(err, net.ErrClosed) {

View File

@ -134,7 +134,7 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
</p> </p>
<Card className={cx( <Card className={cx(
"text-gray-500 dark:text-gray-400 p-4 border", "text-gray-500 dark:text-gray-400 p-4 border",
plugin.status === "errored" && "border-red-200 bg-red-50 text-red-800 dark:text-red-400", plugin.status === "error" && "border-red-200 bg-red-50 text-red-800 dark:text-red-400",
)}> )}>
{plugin.message} {plugin.message}
</Card> </Card>

View File

@ -7,7 +7,7 @@ export function PluginStatusIcon({ plugin }: { plugin: PluginStatus; }) {
classNames = "bg-green-500 border-green-600"; classNames = "bg-green-500 border-green-600";
} else if (plugin.enabled && plugin.status === "pending-configuration") { } else if (plugin.enabled && plugin.status === "pending-configuration") {
classNames = "bg-yellow-500 border-yellow-600"; classNames = "bg-yellow-500 border-yellow-600";
} else if (plugin.enabled && plugin.status === "errored") { } else if (plugin.enabled && plugin.status === "error") {
classNames = "bg-red-500 border-red-600"; classNames = "bg-red-500 border-red-600";
} }

View File

@ -539,7 +539,7 @@ export interface PluginManifest {
export interface PluginStatus extends PluginManifest { export interface PluginStatus extends PluginManifest {
enabled: boolean; enabled: boolean;
status: "stopped" | "running" | "loading" | "pending-configuration" | "errored"; status: "stopped" | "running" | "loading" | "pending-configuration" | "error";
message?: string; message?: string;
} }