vibetunnel/linux/pkg/session/errors.go
2025-06-20 15:43:06 +02:00

165 lines
4.5 KiB
Go

package session
import (
"fmt"
)
// ErrorCode represents standardized error codes matching Node.js implementation
type ErrorCode string
const (
// Session-related errors
ErrSessionNotFound ErrorCode = "SESSION_NOT_FOUND"
ErrSessionAlreadyExists ErrorCode = "SESSION_ALREADY_EXISTS"
ErrSessionStartFailed ErrorCode = "SESSION_START_FAILED"
ErrSessionNotRunning ErrorCode = "SESSION_NOT_RUNNING"
// Process-related errors
ErrProcessNotFound ErrorCode = "PROCESS_NOT_FOUND"
ErrProcessSignalFailed ErrorCode = "PROCESS_SIGNAL_FAILED"
ErrProcessTerminateFailed ErrorCode = "PROCESS_TERMINATE_FAILED"
// I/O related errors
ErrStdinNotFound ErrorCode = "STDIN_NOT_FOUND"
ErrStdinWriteFailed ErrorCode = "STDIN_WRITE_FAILED"
ErrStreamReadFailed ErrorCode = "STREAM_READ_FAILED"
ErrStreamWriteFailed ErrorCode = "STREAM_WRITE_FAILED"
// PTY-related errors
ErrPTYCreationFailed ErrorCode = "PTY_CREATION_FAILED"
ErrPTYConfigFailed ErrorCode = "PTY_CONFIG_FAILED"
ErrPTYResizeFailed ErrorCode = "PTY_RESIZE_FAILED"
// Control-related errors
ErrControlPathNotFound ErrorCode = "CONTROL_PATH_NOT_FOUND"
ErrControlFileCorrupted ErrorCode = "CONTROL_FILE_CORRUPTED"
// Input-related errors
ErrUnknownKey ErrorCode = "UNKNOWN_KEY"
ErrInvalidInput ErrorCode = "INVALID_INPUT"
// General errors
ErrInvalidArgument ErrorCode = "INVALID_ARGUMENT"
ErrPermissionDenied ErrorCode = "PERMISSION_DENIED"
ErrTimeout ErrorCode = "TIMEOUT"
ErrInternal ErrorCode = "INTERNAL_ERROR"
)
// SessionError represents an error with context, matching Node.js PtyError
type SessionError struct {
Message string
Code ErrorCode
SessionID string
Cause error
}
// Error implements the error interface
func (e *SessionError) Error() string {
if e.SessionID != "" {
return fmt.Sprintf("%s (session: %s, code: %s)", e.Message, e.SessionID[:8], e.Code)
}
return fmt.Sprintf("%s (code: %s)", e.Message, e.Code)
}
// Unwrap returns the underlying cause
func (e *SessionError) Unwrap() error {
return e.Cause
}
// NewSessionError creates a new SessionError
func NewSessionError(message string, code ErrorCode, sessionID string) *SessionError {
return &SessionError{
Message: message,
Code: code,
SessionID: sessionID,
}
}
// NewSessionErrorWithCause creates a new SessionError with an underlying cause
func NewSessionErrorWithCause(message string, code ErrorCode, sessionID string, cause error) *SessionError {
return &SessionError{
Message: message,
Code: code,
SessionID: sessionID,
Cause: cause,
}
}
// WrapError wraps an existing error with session context
func WrapError(err error, code ErrorCode, sessionID string) *SessionError {
if err == nil {
return nil
}
// If it's already a SessionError, preserve the original but add context
if se, ok := err.(*SessionError); ok {
return &SessionError{
Message: se.Message,
Code: code,
SessionID: sessionID,
Cause: se,
}
}
return &SessionError{
Message: err.Error(),
Code: code,
SessionID: sessionID,
Cause: err,
}
}
// IsSessionError checks if an error is a SessionError with a specific code
func IsSessionError(err error, code ErrorCode) bool {
se, ok := err.(*SessionError)
return ok && se.Code == code
}
// GetSessionID extracts the session ID from an error if it's a SessionError
func GetSessionID(err error) string {
if se, ok := err.(*SessionError); ok {
return se.SessionID
}
return ""
}
// Common error constructors for convenience
// ErrSessionNotFoundError creates a session not found error
func ErrSessionNotFoundError(sessionID string) *SessionError {
return NewSessionError(
fmt.Sprintf("Session %s not found", sessionID[:8]),
ErrSessionNotFound,
sessionID,
)
}
// ErrProcessSignalError creates a process signal error
func ErrProcessSignalError(sessionID string, signal string, cause error) *SessionError {
return NewSessionErrorWithCause(
fmt.Sprintf("Failed to send signal %s to session", signal),
ErrProcessSignalFailed,
sessionID,
cause,
)
}
// ErrPTYCreationError creates a PTY creation error
func ErrPTYCreationError(sessionID string, cause error) *SessionError {
return NewSessionErrorWithCause(
"Failed to create PTY",
ErrPTYCreationFailed,
sessionID,
cause,
)
}
// ErrStdinWriteError creates a stdin write error
func ErrStdinWriteError(sessionID string, cause error) *SessionError {
return NewSessionErrorWithCause(
"Failed to write to stdin",
ErrStdinWriteFailed,
sessionID,
cause,
)
}