mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 22:55:48 +01:00
* fix(v3): replace various debug logs from Info to Debug * fix(v3): fixed logging on linux as well as windows * fix(v3): add format directive for warning log argument --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
137 lines
3.4 KiB
Go
137 lines
3.4 KiB
Go
package application
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"encoding/json"
|
|
|
|
"github.com/wailsapp/wails/v3/pkg/errs"
|
|
)
|
|
|
|
type contextKey string
|
|
|
|
const (
|
|
CallBinding = 0
|
|
WindowKey contextKey = "Window"
|
|
)
|
|
|
|
func (m *MessageProcessor) processCallCancelMethod(req *RuntimeRequest) (any, error) {
|
|
callID := req.Args.AsMap().String("call-id")
|
|
if callID == nil || *callID == "" {
|
|
return nil, errs.NewInvalidBindingCallErrorf("missing argument 'call-id'")
|
|
}
|
|
|
|
var cancel func()
|
|
func() {
|
|
m.l.Lock()
|
|
defer m.l.Unlock()
|
|
cancel = m.runningCalls[*callID]
|
|
}()
|
|
|
|
if cancel != nil {
|
|
cancel()
|
|
m.Debug("Binding call cancelled:", "id", *callID)
|
|
}
|
|
return unit, nil
|
|
}
|
|
|
|
func (m *MessageProcessor) processCallMethod(ctx context.Context, req *RuntimeRequest, window Window) (any, error) {
|
|
callID := req.Args.AsMap().String("call-id")
|
|
if callID == nil || *callID == "" {
|
|
return nil, errs.NewInvalidBindingCallErrorf("missing argument 'call-id'")
|
|
}
|
|
|
|
switch req.Method {
|
|
case CallBinding:
|
|
var options CallOptions
|
|
err := req.Args.ToStruct(&options)
|
|
if err != nil {
|
|
return nil, errs.WrapInvalidBindingCallErrorf(err, "error parsing call options")
|
|
}
|
|
|
|
// Log call
|
|
var methodRef any = options.MethodName
|
|
if options.MethodName == "" {
|
|
methodRef = options.MethodID
|
|
}
|
|
m.Debug("Binding call started:", "id", *callID, "method", methodRef)
|
|
|
|
ctx, cancel := context.WithCancel(context.WithoutCancel(ctx))
|
|
|
|
// Schedule cancel in case panics happen before starting the call.
|
|
cancelRequired := true
|
|
defer func() {
|
|
if cancelRequired {
|
|
cancel()
|
|
}
|
|
}()
|
|
|
|
ambiguousID := false
|
|
func() {
|
|
m.l.Lock()
|
|
defer m.l.Unlock()
|
|
|
|
if m.runningCalls[*callID] != nil {
|
|
ambiguousID = true
|
|
} else {
|
|
m.runningCalls[*callID] = cancel
|
|
}
|
|
}()
|
|
|
|
if ambiguousID {
|
|
return nil, errs.NewInvalidBindingCallErrorf("ambiguous call id: %s", *callID)
|
|
}
|
|
|
|
defer func() {
|
|
m.l.Lock()
|
|
defer m.l.Unlock()
|
|
delete(m.runningCalls, *callID)
|
|
}()
|
|
defer cancel()
|
|
|
|
var boundMethod *BoundMethod
|
|
if options.MethodName != "" {
|
|
boundMethod = globalApplication.bindings.Get(&options)
|
|
if boundMethod == nil {
|
|
return nil, errs.NewBindingCallFailedErrorf("unknown bound method name '%s'", options.MethodName)
|
|
}
|
|
} else {
|
|
boundMethod = globalApplication.bindings.GetByID(options.MethodID)
|
|
if boundMethod == nil {
|
|
return nil, errs.NewBindingCallFailedErrorf("unknown bound method id %d", options.MethodID)
|
|
}
|
|
}
|
|
|
|
jsonArgs, _ := json.Marshal(options.Args)
|
|
var result any
|
|
defer func() {
|
|
var jsonResult []byte
|
|
jsonResult, _ = json.Marshal(result)
|
|
m.Debug("Binding call complete:", "id", *callID, "method", boundMethod, "args", string(jsonArgs), "result", string(jsonResult))
|
|
}()
|
|
|
|
// Set the context values for the window
|
|
if window != nil {
|
|
ctx = context.WithValue(ctx, WindowKey, window)
|
|
}
|
|
|
|
result, err = boundMethod.Call(ctx, options.Args)
|
|
if cerr := (*CallError)(nil); errors.As(err, &cerr) {
|
|
switch cerr.Kind {
|
|
case ReferenceError, TypeError:
|
|
return nil, errs.WrapBindingCallFailedErrorf(cerr, "failed to call binding")
|
|
case RuntimeError:
|
|
|
|
return nil, errs.WrapBindingCallFailedErrorf(cerr, "Bound method returned an error")
|
|
}
|
|
}
|
|
if err != nil {
|
|
return nil, errs.WrapBindingCallFailedErrorf(err, "failed to call binding")
|
|
}
|
|
return result, nil
|
|
|
|
default:
|
|
return nil, errs.NewInvalidBindingCallErrorf("unknown method: %d", req.Method)
|
|
}
|
|
}
|