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

View File

@ -9,6 +9,7 @@ import (
"net"
"os"
"path"
"slices"
"time"
)
@ -19,12 +20,17 @@ type PluginRpcStatus struct {
var (
PluginRpcStatusDisconnected = PluginRpcStatus{"disconnected", ""}
PluginRpcStatusUnknown = PluginRpcStatus{"unknown", ""}
PluginRpcStatusLoading = PluginRpcStatus{"loading", ""}
PluginRpcStatusPendingConfiguration = PluginRpcStatus{"pending-configuration", ""}
PluginRpcStatusRunning = PluginRpcStatus{"running", ""}
PluginRpcStatusError = PluginRpcStatus{"error", ""}
)
type PluginRpcSupportedMethods struct {
SupportedRpcMethods []string `json:"supported_rpc_methods"`
}
type PluginRpcServer struct {
install *PluginInstall
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
n, err := conn.Read(buf)
if err != nil {
log.Printf("Failed to read message: %v", err)
if errors.Is(err, net.ErrClosed) {
s.status = PluginRpcStatusDisconnected
} else {
log.Printf("Failed to read message: %v", err)
s.status = PluginRpcStatusError
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) {
// log.Printf("Plugin rpc server started. Getting supported methods...")
// 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()
// }
s.status = PluginRpcStatusUnknown
// if supportedMethodsResponse.Error != nil {
// log.Printf("Failed to get supported methods: %v", supportedMethodsResponse.Error)
// s.status = PluginRpcStatusError
// s.status.Message = fmt.Errorf("error getting supported methods: %v", supportedMethodsResponse.Error).Error()
// }
log.Printf("Plugin rpc server started. Getting supported methods...")
var supportedMethodsResponse PluginRpcSupportedMethods
err := rpcserver.Request("getPluginSupportedMethods", nil, &supportedMethodsResponse)
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)
for {
@ -147,7 +155,7 @@ func (s *PluginRpcServer) handleRpcStatus(ctx context.Context, rpcserver *jsonrp
return
case <-ticker.C:
var statusResponse PluginRpcStatus
err := rpcserver.Request("getPluginStatus", map[string]interface{}{}, &statusResponse)
err := rpcserver.Request("getPluginStatus", nil, &statusResponse)
if err != nil {
log.Printf("Failed to get status: %v", err)
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>
<Card className={cx(
"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}
</Card>

View File

@ -7,7 +7,7 @@ export function PluginStatusIcon({ plugin }: { plugin: PluginStatus; }) {
classNames = "bg-green-500 border-green-600";
} else if (plugin.enabled && plugin.status === "pending-configuration") {
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";
}

View File

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