summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exports/exports.go36
-rw-r--r--internal/types/error.go54
-rw-r--r--state.go12
-rw-r--r--wrappers/python/src/__init__.py57
-rw-r--r--wrappers/python/src/main.py6
5 files changed, 131 insertions, 34 deletions
diff --git a/exports/exports.go b/exports/exports.go
index 9f5d18c..468c5a4 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -15,6 +15,7 @@ import "C"
import (
"errors"
+ "encoding/json"
"fmt"
"unsafe"
@@ -92,7 +93,7 @@ func ErrorToString(error error) string {
return ""
}
- return eduvpn.GetErrorTraceback(error)
+ return eduvpn.GetErrorJSONString(error)
}
//export CancelOAuth
@@ -107,40 +108,55 @@ func CancelOAuth(name *C.char) *C.char {
return C.CString(cancelErrString)
}
+type configJSON struct {
+ config string `json:"config"`
+ configType string `json:"config_type"`
+}
+
+func getConfigJSON(config string, configType string) *C.char {
+ json, jsonErr := json.Marshal(&configJSON{config, configType})
+
+ if jsonErr != nil {
+ panic(jsonErr)
+ }
+
+ return C.CString(string(json))
+}
+
//export GetConfigSecureInternet
-func GetConfigSecureInternet(name *C.char, orgID *C.char, forceTCP C.int) (*C.char, *C.char, *C.char) {
+func GetConfigSecureInternet(name *C.char, orgID *C.char, forceTCP C.int) (*C.char, *C.char) {
nameStr := C.GoString(name)
state, stateErr := GetVPNState(nameStr)
if stateErr != nil {
- return nil, nil, C.CString(ErrorToString(stateErr))
+ return nil, C.CString(ErrorToString(stateErr))
}
forceTCPBool := forceTCP == 1
config, configType, configErr := state.GetConfigSecureInternet(C.GoString(orgID), forceTCPBool)
- return C.CString(config), C.CString(configType), C.CString(ErrorToString(configErr))
+ return getConfigJSON(config, configType), C.CString(ErrorToString(configErr))
}
//export GetConfigInstituteAccess
-func GetConfigInstituteAccess(name *C.char, url *C.char, forceTCP C.int) (*C.char, *C.char, *C.char) {
+func GetConfigInstituteAccess(name *C.char, url *C.char, forceTCP C.int) (*C.char, *C.char) {
nameStr := C.GoString(name)
state, stateErr := GetVPNState(nameStr)
if stateErr != nil {
- return nil, nil, C.CString(ErrorToString(stateErr))
+ return nil, C.CString(ErrorToString(stateErr))
}
forceTCPBool := forceTCP == 1
config, configType, configErr := state.GetConfigInstituteAccess(C.GoString(url), forceTCPBool)
- return C.CString(config), C.CString(configType), C.CString(ErrorToString(configErr))
+ return getConfigJSON(config, configType), C.CString(ErrorToString(configErr))
}
//export GetConfigCustomServer
-func GetConfigCustomServer(name *C.char, url *C.char, forceTCP C.int) (*C.char, *C.char, *C.char) {
+func GetConfigCustomServer(name *C.char, url *C.char, forceTCP C.int) (*C.char, *C.char) {
nameStr := C.GoString(name)
state, stateErr := GetVPNState(nameStr)
if stateErr != nil {
- return nil, nil, C.CString(ErrorToString(stateErr))
+ return nil, C.CString(ErrorToString(stateErr))
}
forceTCPBool := forceTCP == 1
config, configType, configErr := state.GetConfigCustomServer(C.GoString(url), forceTCPBool)
- return C.CString(config), C.CString(configType), C.CString(ErrorToString(configErr))
+ return getConfigJSON(config, configType), C.CString(ErrorToString(configErr))
}
//export GetDiscoOrganizations
diff --git a/internal/types/error.go b/internal/types/error.go
index fda7c9c..e5bd082 100644
--- a/internal/types/error.go
+++ b/internal/types/error.go
@@ -2,10 +2,22 @@ package types
import (
"errors"
+ "encoding/json"
"fmt"
)
+type ErrorLevel int8
+
+const (
+ // All other errors
+ ERR_OTHER ErrorLevel = iota
+
+ // The error is just here as additional info
+ ERR_INFO
+)
+
type WrappedErrorMessage struct {
+ Level ErrorLevel
Message string
Err error
}
@@ -60,3 +72,45 @@ func GetErrorCause(err error) error {
}
return err
}
+
+func GetErrorLevel(err error) ErrorLevel {
+ var wrappedErr *WrappedErrorMessage
+
+ if errors.As(err, &wrappedErr) {
+ return wrappedErr.Level
+ }
+ return ERR_OTHER
+}
+
+type WrappedErrorMessageJSON struct {
+ Level ErrorLevel `json:"level"`
+ Cause string `json:"cause"`
+ Traceback string `json:"traceback"`
+}
+
+
+func GetErrorJSONString(err error) string {
+ var wrappedErr *WrappedErrorMessage
+
+ var level ErrorLevel
+ var cause error
+ var traceback string
+
+ if errors.As(err, &wrappedErr) {
+ level = wrappedErr.Level
+ cause = wrappedErr.Cause()
+ traceback = wrappedErr.Traceback()
+ } else {
+ level = ERR_OTHER
+ cause = err
+ traceback = err.Error()
+ }
+
+
+ json, jsonErr := json.Marshal(&WrappedErrorMessageJSON{Level: level, Cause: cause.Error(), Traceback: traceback})
+
+ if jsonErr != nil {
+ panic(jsonErr)
+ }
+ return string(json)
+}
diff --git a/state.go b/state.go
index a175e2f..d4aa3df 100644
--- a/state.go
+++ b/state.go
@@ -336,10 +336,18 @@ func (state *VPNState) SetDisconnected() error {
return nil
}
+func GetErrorCause(err error) error {
+ return types.GetErrorCause(err)
+}
+
+func GetErrorLevel(err error) types.ErrorLevel {
+ return types.GetErrorLevel(err)
+}
+
func GetErrorTraceback(err error) string {
return types.GetErrorTraceback(err)
}
-func GetErrorCause(err error) error {
- return types.GetErrorCause(err)
+func GetErrorJSONString(err error) string {
+ return types.GetErrorJSONString(err)
}
diff --git a/wrappers/python/src/__init__.py b/wrappers/python/src/__init__.py
index f361ad1..0451f61 100644
--- a/wrappers/python/src/__init__.py
+++ b/wrappers/python/src/__init__.py
@@ -1,8 +1,10 @@
from ctypes import *
from collections import defaultdict
+from enum import Enum
import pathlib
import platform
-from typing import Tuple
+from typing import Tuple, Optional
+import json
_lib_prefixes = defaultdict(
lambda: "lib",
@@ -33,15 +35,14 @@ try:
except:
lib = cdll.LoadLibrary(str(pathlib.Path(__file__).parent / "lib" / _libfile))
+class ErrorLevel(Enum):
+ ERR_OTHER = 0
+ ERR_INFO = 1
class DataError(Structure):
_fields_ = [("data", c_void_p), ("error", c_void_p)]
-class MultipleDataError(Structure):
- _fields_ = [("data", c_void_p), ("other_data", c_void_p), ("error", c_void_p)]
-
-
VPNStateChange = CFUNCTYPE(None, c_char_p, c_char_p, c_char_p, c_char_p)
# Exposed functions
@@ -51,17 +52,17 @@ lib.GetConfigSecureInternet.argtypes, lib.GetConfigSecureInternet.restype = [
c_char_p,
c_char_p,
c_int,
-], MultipleDataError
+], DataError
lib.GetConfigInstituteAccess.argtypes, lib.GetConfigInstituteAccess.restype = [
c_char_p,
c_char_p,
c_int,
-], MultipleDataError
+], DataError
lib.GetConfigCustomServer.argtypes, lib.GetConfigCustomServer.restype = [
c_char_p,
c_char_p,
c_int,
-], MultipleDataError
+], DataError
lib.Deregister.argtypes, lib.Deregister.restype = [c_char_p], c_void_p
lib.Register.argtypes, lib.Register.restype = [
c_char_p,
@@ -87,6 +88,13 @@ lib.SetSearchServer.argtypes, lib.SetSearchServer.restype = [c_char_p], c_void_p
lib.FreeString.argtypes, lib.FreeString.restype = [c_void_p], None
+class WrappedError:
+ def __init__(self, traceback: str, cause: str, level: ErrorLevel):
+ self.traceback = traceback
+ self.cause = cause
+ self.level = level
+
+
def encode_args(args, types):
for arg, t in zip(args, types):
# c_char_p needs the str to be encoded to bytes
@@ -107,24 +115,33 @@ def get_ptr_string(ptr: c_void_p) -> str:
return string.decode()
return ""
+def get_ptr_error(ptr: c_void_p) -> Optional[WrappedError]:
+ error_string = get_ptr_string(ptr)
+
+ if not error_string:
+ return None
+
+ error_json = json.loads(error_string)
+
+ if not error_json:
+ return None
+
+ level = error_json["level"]
+ traceback = error_json["traceback"]
+ cause = error_json["cause"]
+ return WrappedError(traceback, cause, ErrorLevel(level))
def get_data_error(data_error: DataError) -> Tuple[str, str]:
data = get_ptr_string(data_error.data)
- error = get_ptr_string(data_error.error)
+ error = get_ptr_error(data_error.error)
+ if not error:
+ error = ""
+ else:
+ error = error.traceback
return data, error
-def get_multiple_data_error(
- multiple_data_error: MultipleDataError,
-) -> Tuple[str, str, str]:
- data = get_ptr_string(multiple_data_error.data)
- other_data = get_ptr_string(multiple_data_error.other_data)
- error = get_ptr_string(multiple_data_error.error)
- return data, other_data, error
-
-
decode_map = {
- c_void_p: get_ptr_string,
+ c_void_p: get_ptr_error,
DataError: get_data_error,
- MultipleDataError: get_multiple_data_error,
}
diff --git a/wrappers/python/src/main.py b/wrappers/python/src/main.py
index 3707d16..6f4b140 100644
--- a/wrappers/python/src/main.py
+++ b/wrappers/python/src/main.py
@@ -1,5 +1,4 @@
from . import lib, VPNStateChange, encode_args, decode_res
-from enum import Enum
from typing import Optional, Tuple
import threading
from .event import StateType, EventHandler
@@ -103,7 +102,7 @@ class EduVPN(object):
# The event is set in self.set_profile
self.profile_event = threading.Event()
- config, config_type, config_err = self.go_function(func, url, force_tcp)
+ config_json, config_err = self.go_function(func, url, force_tcp)
self.profile_event = None
self.location_event = None
@@ -111,6 +110,9 @@ class EduVPN(object):
if config_err:
raise Exception(config_err)
+ config = config_json["config"]
+ config_type = config_json["config_type"]
+
return config, config_type
def get_config_custom_server(