Skip to content

refactor: refactored all handlers into a callback map#144

Merged
gmegidish merged 2 commits intomainfrom
refactor-handler-map
Jan 17, 2026
Merged

refactor: refactored all handlers into a callback map#144
gmegidish merged 2 commits intomainfrom
refactor-handler-map

Conversation

@gmegidish
Copy link
Member

@gmegidish gmegidish commented Jan 17, 2026

Summary by CodeRabbit

  • New Features

    • Added a centralized method registry API for JSON-RPC operations to streamline method lookup and invocation.
  • Refactor

    • Reworked RPC dispatch to route non-streaming calls through the registry and unify execution flow.
  • Bug Fixes / Improvements

    • Explicit error for missing/empty methods, improved error logging, streaming-special handling for screen capture, and extended timeout for device boot operations.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 17, 2026

Walkthrough

Adds a registry-based JSON-RPC dispatch for non-streaming methods and an Execute entry point for embedded clients; refactors server dispatch to use the registry while preserving special streaming and extended-timeout handling for screencapture and device_boot.

Changes

Cohort / File(s) Summary
New dispatch registry module
server/dispatch.go
Adds HandlerFunc (func(params json.RawMessage) (interface{}, error)), GetMethodRegistry() returning method→handler mappings (e.g., devices, screenshot, io_*, url, device_info, device_boot, device_shutdown, device_reboot, dump_ui, apps_*), and Execute(method, params) as embedded-client entry point.
Refactored server dispatch
server/server.go
Replaces large switch-based dispatch with registry lookup via GetMethodRegistry(). Keeps special-case streaming path for screencapture and extends HTTP write timeout for device_boot. Changes handleDeviceBoot signature from func(w http.ResponseWriter, params json.RawMessage) (interface{}, error) to func(params json.RawMessage) (interface{}, error); adds unknown-method and screencapture error handling.
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring work: consolidating handler dispatch from explicit switch-case logic into a registry-driven callback map pattern, which is the central theme of the changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@server/server.go`:
- Around line 169-181: When req.Method is empty, don't set a generic err and let
the later decoding error path run; instead immediately call sendJSONRPCError
with ErrCodeInvalidRequest (-32600) and a clear message (e.g. "Invalid Request"
and data like "method is required or empty"), then return. Update the req.Method
== "" branch to use sendJSONRPCError(w, req.ID, ErrCodeInvalidRequest, "Invalid
Request", "Method is required or empty") and remove the assignment that causes
the misleading "Error decoding JSON-RPC request"/ErrCodeServerError handling;
keep the existing registry lookup (GetMethodRegistry, handler) unchanged.
🧹 Nitpick comments (2)
server/dispatch.go (1)

13-35: Consider caching the registry map.

GetMethodRegistry() allocates a new map on every call. If this function is invoked per-request, the repeated allocations add unnecessary GC pressure. Consider initializing the map once at package level or using sync.Once.

♻️ Suggested refactor using package-level initialization
+var methodRegistry = map[string]HandlerFunc{
+	"devices":            handleDevicesList,
+	"screenshot":         handleScreenshot,
+	"io_tap":             handleIoTap,
+	"io_longpress":       handleIoLongPress,
+	"io_text":            handleIoText,
+	"io_button":          handleIoButton,
+	"io_swipe":           handleIoSwipe,
+	"io_gesture":         handleIoGesture,
+	"url":                handleURL,
+	"device_info":        handleDeviceInfo,
+	"io_orientation_get": handleIoOrientationGet,
+	"io_orientation_set": handleIoOrientationSet,
+	"device_boot":        handleDeviceBoot,
+	"device_shutdown":    handleDeviceShutdown,
+	"device_reboot":      handleDeviceReboot,
+	"dump_ui":            handleDumpUI,
+	"apps_launch":        handleAppsLaunch,
+	"apps_terminate":     handleAppsTerminate,
+	"apps_list":          handleAppsList,
+}
+
 // GetMethodRegistry returns a map of method names to handler functions
 // This is used by both the HTTP server and embedded clients
 func GetMethodRegistry() map[string]HandlerFunc {
-	return map[string]HandlerFunc{
-		"devices":            handleDevicesList,
-		...
-	}
+	return methodRegistry
 }
server/server.go (1)

183-186: Misleading log message.

The log message "Error decoding JSON-RPC request" is inaccurate at this point—decoding has already succeeded. This error comes from handler execution.

💡 Suggested fix
 	if err != nil {
-		log.Printf("Error decoding JSON-RPC request: %v", err)
+		log.Printf("Error executing method '%s': %v", req.Method, err)
 		sendJSONRPCError(w, req.ID, ErrCodeServerError, "Server error", err.Error())
 		return
 	}

Comment on lines +169 to +181
// Use registry for all methods
if req.Method == "" {
err = fmt.Errorf("'method' is required")
} else {
registry := GetMethodRegistry()
handler, exists := registry[req.Method]
if exists {
result, err = handler(req.Params)
} else {
sendJSONRPCError(w, req.ID, ErrCodeMethodNotFound, "Method not found", fmt.Sprintf("Method '%s' not found", req.Method))
return
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Empty method error uses incorrect error code and misleading log message.

When req.Method is empty, the error flows to line 184-185 which logs "Error decoding JSON-RPC request" (misleading since decoding succeeded) and returns ErrCodeServerError. Per JSON-RPC spec, a missing/empty method should return ErrCodeInvalidRequest (-32600).

🔧 Suggested fix
 	// Use registry for all methods
 	if req.Method == "" {
-		err = fmt.Errorf("'method' is required")
+		sendJSONRPCError(w, req.ID, ErrCodeInvalidRequest, "Invalid Request", "'method' is required")
+		return
 	} else {
 		registry := GetMethodRegistry()
 		handler, exists := registry[req.Method]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Use registry for all methods
if req.Method == "" {
err = fmt.Errorf("'method' is required")
} else {
registry := GetMethodRegistry()
handler, exists := registry[req.Method]
if exists {
result, err = handler(req.Params)
} else {
sendJSONRPCError(w, req.ID, ErrCodeMethodNotFound, "Method not found", fmt.Sprintf("Method '%s' not found", req.Method))
return
}
}
// Use registry for all methods
if req.Method == "" {
sendJSONRPCError(w, req.ID, ErrCodeInvalidRequest, "Invalid Request", "'method' is required")
return
} else {
registry := GetMethodRegistry()
handler, exists := registry[req.Method]
if exists {
result, err = handler(req.Params)
} else {
sendJSONRPCError(w, req.ID, ErrCodeMethodNotFound, "Method not found", fmt.Sprintf("Method '%s' not found", req.Method))
return
}
}
🤖 Prompt for AI Agents
In `@server/server.go` around lines 169 - 181, When req.Method is empty, don't set
a generic err and let the later decoding error path run; instead immediately
call sendJSONRPCError with ErrCodeInvalidRequest (-32600) and a clear message
(e.g. "Invalid Request" and data like "method is required or empty"), then
return. Update the req.Method == "" branch to use sendJSONRPCError(w, req.ID,
ErrCodeInvalidRequest, "Invalid Request", "Method is required or empty") and
remove the assignment that causes the misleading "Error decoding JSON-RPC
request"/ErrCodeServerError handling; keep the existing registry lookup
(GetMethodRegistry, handler) unchanged.

@gmegidish gmegidish merged commit af9d86d into main Jan 17, 2026
15 checks passed
@gmegidish gmegidish deleted the refactor-handler-map branch January 17, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant