mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-03-26 09:35:52 +00:00
165 lines
4.5 KiB
Go
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,
|
|
)
|
|
}
|