github.com/secoba/wails/v2@v2.6.4/internal/frontend/dispatcher/calls.go (about)

     1  package dispatcher
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/secoba/wails/v2/internal/frontend"
     9  )
    10  
    11  type callMessage struct {
    12  	Name       string            `json:"name"`
    13  	Args       []json.RawMessage `json:"args"`
    14  	CallbackID string            `json:"callbackID"`
    15  }
    16  
    17  func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend) (string, error) {
    18  	var payload callMessage
    19  	err := json.Unmarshal([]byte(message[1:]), &payload)
    20  	if err != nil {
    21  		return "", err
    22  	}
    23  
    24  	var result interface{}
    25  
    26  	// Handle different calls
    27  	switch true {
    28  	case strings.HasPrefix(payload.Name, systemCallPrefix):
    29  		result, err = d.processSystemCall(payload, sender)
    30  	default:
    31  		// Lookup method
    32  		registeredMethod := d.bindingsDB.GetMethod(payload.Name)
    33  
    34  		// Check we have it
    35  		if registeredMethod == nil {
    36  			return "", fmt.Errorf("method '%s' not registered", payload.Name)
    37  		}
    38  
    39  		args, err2 := registeredMethod.ParseArgs(payload.Args)
    40  		if err2 != nil {
    41  			errmsg := fmt.Errorf("error parsing arguments: %s", err2.Error())
    42  			result, _ := d.NewErrorCallback(errmsg.Error(), payload.CallbackID)
    43  			return result, errmsg
    44  		}
    45  		result, err = registeredMethod.Call(args)
    46  	}
    47  
    48  	callbackMessage := &CallbackMessage{
    49  		CallbackID: payload.CallbackID,
    50  	}
    51  	if err != nil {
    52  		// Use the error formatter if one was provided
    53  		if d.errfmt != nil {
    54  			callbackMessage.Err = d.errfmt(err)
    55  		} else {
    56  			callbackMessage.Err = err.Error()
    57  		}
    58  	} else {
    59  		callbackMessage.Result = result
    60  	}
    61  	messageData, err := json.Marshal(callbackMessage)
    62  	d.log.Trace("json call result data: %+v\n", string(messageData))
    63  	if err != nil {
    64  		// what now?
    65  		d.log.Fatal(err.Error())
    66  	}
    67  
    68  	return "c" + string(messageData), nil
    69  }
    70  
    71  // CallbackMessage defines a message that contains the result of a call
    72  type CallbackMessage struct {
    73  	Result     interface{} `json:"result"`
    74  	Err        any         `json:"error"`
    75  	CallbackID string      `json:"callbackid"`
    76  }
    77  
    78  func (d *Dispatcher) NewErrorCallback(message string, callbackID string) (string, error) {
    79  	result := &CallbackMessage{
    80  		CallbackID: callbackID,
    81  		Err:        message,
    82  	}
    83  	messageData, err := json.Marshal(result)
    84  	d.log.Trace("json call result data: %+v\n", string(messageData))
    85  	return string(messageData), err
    86  }