Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type cast panic when using RPC #1475

Closed
daniloarcidiacono opened this issue Sep 1, 2022 · 0 comments · Fixed by #1501
Closed

Type cast panic when using RPC #1475

daniloarcidiacono opened this issue Sep 1, 2022 · 0 comments · Fixed by #1501
Assignees
Milestone

Comments

@daniloarcidiacono
Copy link

Hello,
I'd like to develop a custom RPC backend but the ListFlags method in remote.go unmarshals the response as a generic []interface{}. This causes problems when the callers of ListFlags try to downcast the result to either []string or []store.BlockedUser.
The memory_store example backend has the same problem.

I tried to fix that method with:

func unmarshalString(data[] byte) (list []interface{}, err error) {
	var typedList []string
	err = json.Unmarshal(data, &typedList)
	if err == nil {
		// https://go101.org/article/interface.html
		list := make([]interface{}, 0, len(typedList))
		for _, w := range typedList {
			list = append(list, w)
		}

		return list, err
	}

	return nil, err
}

func unmarshalBlockedUser(data[] byte) (list []interface{}, err error) {
	var typedList []store.BlockedUser
	err = json.Unmarshal(data, &typedList)
	if err == nil {
		// https://go101.org/article/interface.html
		list := make([]interface{}, 0, len(typedList))
		for _, w := range typedList {
			list = append(list, w)
		}

		return list, err
	}

	return nil, err
}

// ListFlags get list of flagged keys, like blocked & verified user
func (r *RPC) ListFlags(req FlagRequest) (list []interface{}, err error) {
	resp, err := r.Call("store.list_flags", req)
	if err != nil {
		return nil, err
	}

	// Try store.BlockedUser
	list, err = unmarshalBlockedUser(*resp.Result)
	if err == nil {
		return list, err
	}

	// Try strings
	list, err = unmarshalString(*resp.Result)
	if err == nil {
		return list, err
	}
	
	// Generic (but it won't work)
	err = json.Unmarshal(*resp.Result, &list)
	return list, err
}

Method generics help a bit but they require Go 1.18

func polyUnmarshal[C any](data[] byte) (list []any, err error) {
	var typedList []C
	err = json.Unmarshal(data, &typedList)
	if err == nil {
		// https://go101.org/article/interface.html
		list := make([]interface{}, 0, len(typedList))
		for _, w := range typedList {
			list = append(list, w)
		}

		return list, err
	}

	return nil, err
}

Probably there is a better approach to solve this issue, I'm not a Go developer.
Thanks

@paskal paskal self-assigned this Sep 12, 2022
paskal added a commit that referenced this issue Sep 28, 2022
Fixes the following conversion problem for BlockedUser:

panic: interface conversion:
interface {} is map[string]interface {},not store.BlockedUser [recovered]

Resolves #1475.
paskal added a commit that referenced this issue Sep 28, 2022
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves #1475.
paskal added a commit that referenced this issue Sep 28, 2022
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves #1475.
paskal added a commit that referenced this issue Sep 28, 2022
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves #1475.
paskal added a commit that referenced this issue Sep 28, 2022
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves #1475.
paskal added a commit that referenced this issue Sep 28, 2022
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves #1475.
umputun pushed a commit that referenced this issue Sep 29, 2022
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves #1475.
@paskal paskal added this to the v1.11.0 milestone Jan 15, 2023
itzomen pushed a commit to traleor/comments that referenced this issue Apr 16, 2023
Fixes the following conversion problem for BlockedUser:

```
panic: interface conversion: interface {} is map[string]interface {},
not store.BlockedUser [recovered]
```

Resolves umputun#1475.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants