MM-11734: better plugin error handling (#9405)

* MM-11734: encode unregistered error implementations as an ErrorString

* MM-11734: test error string handling

* more idiomatic error handling
Этот коммит содержится в:
Jesse Hallam
2018-09-13 14:31:22 -04:00
коммит произвёл Christopher Speller
родитель 8b17bf9e42
Коммит f2ddef9117
4 изменённых файлов: 241 добавлений и 83 удалений

Просмотреть файл

@@ -13,6 +13,8 @@ import (
"testing"
"time"
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
"github.com/mattermost/mattermost-server/plugin/plugintest"
@@ -33,7 +35,7 @@ func compileGo(t *testing.T, sourceCode, outputPath string) {
require.NoError(t, cmd.Run())
}
func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, apiFunc func(*model.Manifest) plugin.API) {
func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, apiFunc func(*model.Manifest) plugin.API) []error {
pluginDir, err := ioutil.TempDir("", "")
require.NoError(t, err)
webappPluginDir, err := ioutil.TempDir("", "")
@@ -45,14 +47,18 @@ func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, a
require.NoError(t, err)
app.Plugins = env
activationErrors := []error{}
for _, code := range pluginCode {
pluginId := model.NewId()
backend := filepath.Join(pluginDir, pluginId, "backend.exe")
compileGo(t, code, backend)
ioutil.WriteFile(filepath.Join(pluginDir, pluginId, "plugin.json"), []byte(`{"id": "`+pluginId+`", "backend": {"executable": "backend.exe"}}`), 0600)
env.Activate(pluginId)
_, _, activationErr := env.Activate(pluginId)
activationErrors = append(activationErrors, activationErr)
}
return activationErrors
}
func TestHookMessageWillBePosted(t *testing.T) {
@@ -791,3 +797,73 @@ func TestUserHasLoggedIn(t *testing.T) {
t.Errorf("Expected firstname overwrite, got default")
}
}
func TestErrorString(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
t.Run("errors.New", func(t *testing.T) {
activationErrors := SetAppEnvironmentWithPlugins(t,
[]string{
`
package main
import (
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/plugin"
)
type MyPlugin struct {
plugin.MattermostPlugin
}
func (p *MyPlugin) OnActivate() error {
return errors.New("simulate failure")
}
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.App.NewPluginAPI)
require.Len(t, activationErrors, 1)
require.NotNil(t, activationErrors[0])
require.Contains(t, activationErrors[0].Error(), "simulate failure")
})
t.Run("AppError", func(t *testing.T) {
activationErrors := SetAppEnvironmentWithPlugins(t,
[]string{
`
package main
import (
"github.com/mattermost/mattermost-server/plugin"
"github.com/mattermost/mattermost-server/model"
)
type MyPlugin struct {
plugin.MattermostPlugin
}
func (p *MyPlugin) OnActivate() error {
return model.NewAppError("where", "id", map[string]interface{}{"param": 1}, "details", 42)
}
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.App.NewPluginAPI)
require.Len(t, activationErrors, 1)
require.NotNil(t, activationErrors[0])
cause := errors.Cause(activationErrors[0])
require.IsType(t, &model.AppError{}, cause)
// params not expected, since not exported
expectedErr := model.NewAppError("where", "id", nil, "details", 42)
require.Equal(t, expectedErr, cause)
})
}

Просмотреть файл

@@ -62,12 +62,39 @@ type apiRPCServer struct {
impl API
}
// ErrorString is a fallback for sending unregistered implementations of the error interface across
// rpc. For example, the errorString type from the github.com/pkg/errors package cannot be
// registered since it is not exported, but this precludes common error handling paradigms.
// ErrorString merely preserves the string description of the error, while satisfying the error
// interface itself to allow other registered types (such as model.AppError) to be sent unmodified.
type ErrorString struct {
Err string
}
func (e ErrorString) Error() string {
return e.Err
}
func encodableError(err error) error {
if err == nil {
return nil
}
if _, ok := err.(*model.AppError); ok {
return err
}
return &ErrorString{
Err: err.Error(),
}
}
// Registering some types used by MM for encoding/gob used by rpc
func init() {
gob.Register([]*model.SlackAttachment{})
gob.Register([]interface{}{})
gob.Register(map[string]interface{}{})
gob.Register(&model.AppError{})
gob.Register(&ErrorString{})
}
// These enforce compile time checks to make sure types implement the interface
@@ -128,7 +155,7 @@ func (s *hooksRPCServer) Implemented(args struct{}, reply *[]string) error {
methods = append(methods, method.Name)
}
*reply = methods
return nil
return encodableError(nil)
}
type Z_OnActivateArgs struct {
@@ -182,7 +209,7 @@ func (s *hooksRPCServer) OnActivate(args *Z_OnActivateArgs, returns *Z_OnActivat
if hook, ok := s.impl.(interface {
OnActivate() error
}); ok {
returns.A = hook.OnActivate()
returns.A = encodableError(hook.OnActivate())
}
return nil
}

Просмотреть файл

@@ -41,8 +41,9 @@ func (s *hooksRPCServer) OnDeactivate(args *Z_OnDeactivateArgs, returns *Z_OnDea
OnDeactivate() error
}); ok {
returns.A = hook.OnDeactivate()
returns.A = encodableError(returns.A)
} else {
return fmt.Errorf("Hook OnDeactivate called but not implemented.")
return encodableError(fmt.Errorf("Hook OnDeactivate called but not implemented."))
}
return nil
}
@@ -74,8 +75,9 @@ func (s *hooksRPCServer) OnConfigurationChange(args *Z_OnConfigurationChangeArgs
OnConfigurationChange() error
}); ok {
returns.A = hook.OnConfigurationChange()
returns.A = encodableError(returns.A)
} else {
return fmt.Errorf("Hook OnConfigurationChange called but not implemented.")
return encodableError(fmt.Errorf("Hook OnConfigurationChange called but not implemented."))
}
return nil
}
@@ -110,8 +112,9 @@ func (s *hooksRPCServer) ExecuteCommand(args *Z_ExecuteCommandArgs, returns *Z_E
ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError)
}); ok {
returns.A, returns.B = hook.ExecuteCommand(args.A, args.B)
} else {
return fmt.Errorf("Hook ExecuteCommand called but not implemented.")
return encodableError(fmt.Errorf("Hook ExecuteCommand called but not implemented."))
}
return nil
}
@@ -146,8 +149,9 @@ func (s *hooksRPCServer) MessageWillBePosted(args *Z_MessageWillBePostedArgs, re
MessageWillBePosted(c *Context, post *model.Post) (*model.Post, string)
}); ok {
returns.A, returns.B = hook.MessageWillBePosted(args.A, args.B)
} else {
return fmt.Errorf("Hook MessageWillBePosted called but not implemented.")
return encodableError(fmt.Errorf("Hook MessageWillBePosted called but not implemented."))
}
return nil
}
@@ -183,8 +187,9 @@ func (s *hooksRPCServer) MessageWillBeUpdated(args *Z_MessageWillBeUpdatedArgs,
MessageWillBeUpdated(c *Context, newPost, oldPost *model.Post) (*model.Post, string)
}); ok {
returns.A, returns.B = hook.MessageWillBeUpdated(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook MessageWillBeUpdated called but not implemented.")
return encodableError(fmt.Errorf("Hook MessageWillBeUpdated called but not implemented."))
}
return nil
}
@@ -217,8 +222,9 @@ func (s *hooksRPCServer) MessageHasBeenPosted(args *Z_MessageHasBeenPostedArgs,
MessageHasBeenPosted(c *Context, post *model.Post)
}); ok {
hook.MessageHasBeenPosted(args.A, args.B)
} else {
return fmt.Errorf("Hook MessageHasBeenPosted called but not implemented.")
return encodableError(fmt.Errorf("Hook MessageHasBeenPosted called but not implemented."))
}
return nil
}
@@ -252,8 +258,9 @@ func (s *hooksRPCServer) MessageHasBeenUpdated(args *Z_MessageHasBeenUpdatedArgs
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
}); ok {
hook.MessageHasBeenUpdated(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook MessageHasBeenUpdated called but not implemented.")
return encodableError(fmt.Errorf("Hook MessageHasBeenUpdated called but not implemented."))
}
return nil
}
@@ -286,8 +293,9 @@ func (s *hooksRPCServer) ChannelHasBeenCreated(args *Z_ChannelHasBeenCreatedArgs
ChannelHasBeenCreated(c *Context, channel *model.Channel)
}); ok {
hook.ChannelHasBeenCreated(args.A, args.B)
} else {
return fmt.Errorf("Hook ChannelHasBeenCreated called but not implemented.")
return encodableError(fmt.Errorf("Hook ChannelHasBeenCreated called but not implemented."))
}
return nil
}
@@ -321,8 +329,9 @@ func (s *hooksRPCServer) UserHasJoinedChannel(args *Z_UserHasJoinedChannelArgs,
UserHasJoinedChannel(c *Context, channelMember *model.ChannelMember, actor *model.User)
}); ok {
hook.UserHasJoinedChannel(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook UserHasJoinedChannel called but not implemented.")
return encodableError(fmt.Errorf("Hook UserHasJoinedChannel called but not implemented."))
}
return nil
}
@@ -356,8 +365,9 @@ func (s *hooksRPCServer) UserHasLeftChannel(args *Z_UserHasLeftChannelArgs, retu
UserHasLeftChannel(c *Context, channelMember *model.ChannelMember, actor *model.User)
}); ok {
hook.UserHasLeftChannel(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook UserHasLeftChannel called but not implemented.")
return encodableError(fmt.Errorf("Hook UserHasLeftChannel called but not implemented."))
}
return nil
}
@@ -391,8 +401,9 @@ func (s *hooksRPCServer) UserHasJoinedTeam(args *Z_UserHasJoinedTeamArgs, return
UserHasJoinedTeam(c *Context, teamMember *model.TeamMember, actor *model.User)
}); ok {
hook.UserHasJoinedTeam(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook UserHasJoinedTeam called but not implemented.")
return encodableError(fmt.Errorf("Hook UserHasJoinedTeam called but not implemented."))
}
return nil
}
@@ -426,8 +437,9 @@ func (s *hooksRPCServer) UserHasLeftTeam(args *Z_UserHasLeftTeamArgs, returns *Z
UserHasLeftTeam(c *Context, teamMember *model.TeamMember, actor *model.User)
}); ok {
hook.UserHasLeftTeam(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook UserHasLeftTeam called but not implemented.")
return encodableError(fmt.Errorf("Hook UserHasLeftTeam called but not implemented."))
}
return nil
}
@@ -461,8 +473,9 @@ func (s *hooksRPCServer) UserWillLogIn(args *Z_UserWillLogInArgs, returns *Z_Use
UserWillLogIn(c *Context, user *model.User) string
}); ok {
returns.A = hook.UserWillLogIn(args.A, args.B)
} else {
return fmt.Errorf("Hook UserWillLogIn called but not implemented.")
return encodableError(fmt.Errorf("Hook UserWillLogIn called but not implemented."))
}
return nil
}
@@ -495,8 +508,9 @@ func (s *hooksRPCServer) UserHasLoggedIn(args *Z_UserHasLoggedInArgs, returns *Z
UserHasLoggedIn(c *Context, user *model.User)
}); ok {
hook.UserHasLoggedIn(args.A, args.B)
} else {
return fmt.Errorf("Hook UserHasLoggedIn called but not implemented.")
return encodableError(fmt.Errorf("Hook UserHasLoggedIn called but not implemented."))
}
return nil
}
@@ -524,7 +538,7 @@ func (s *apiRPCServer) RegisterCommand(args *Z_RegisterCommandArgs, returns *Z_R
}); ok {
returns.A = hook.RegisterCommand(args.A)
} else {
return fmt.Errorf("API RegisterCommand called but not implemented.")
return encodableError(fmt.Errorf("API RegisterCommand called but not implemented."))
}
return nil
}
@@ -553,7 +567,7 @@ func (s *apiRPCServer) UnregisterCommand(args *Z_UnregisterCommandArgs, returns
}); ok {
returns.A = hook.UnregisterCommand(args.A, args.B)
} else {
return fmt.Errorf("API UnregisterCommand called but not implemented.")
return encodableError(fmt.Errorf("API UnregisterCommand called but not implemented."))
}
return nil
}
@@ -582,7 +596,7 @@ func (s *apiRPCServer) GetSession(args *Z_GetSessionArgs, returns *Z_GetSessionR
}); ok {
returns.A, returns.B = hook.GetSession(args.A)
} else {
return fmt.Errorf("API GetSession called but not implemented.")
return encodableError(fmt.Errorf("API GetSession called but not implemented."))
}
return nil
}
@@ -609,7 +623,7 @@ func (s *apiRPCServer) GetConfig(args *Z_GetConfigArgs, returns *Z_GetConfigRetu
}); ok {
returns.A = hook.GetConfig()
} else {
return fmt.Errorf("API GetConfig called but not implemented.")
return encodableError(fmt.Errorf("API GetConfig called but not implemented."))
}
return nil
}
@@ -637,7 +651,7 @@ func (s *apiRPCServer) SaveConfig(args *Z_SaveConfigArgs, returns *Z_SaveConfigR
}); ok {
returns.A = hook.SaveConfig(args.A)
} else {
return fmt.Errorf("API SaveConfig called but not implemented.")
return encodableError(fmt.Errorf("API SaveConfig called but not implemented."))
}
return nil
}
@@ -666,7 +680,7 @@ func (s *apiRPCServer) CreateUser(args *Z_CreateUserArgs, returns *Z_CreateUserR
}); ok {
returns.A, returns.B = hook.CreateUser(args.A)
} else {
return fmt.Errorf("API CreateUser called but not implemented.")
return encodableError(fmt.Errorf("API CreateUser called but not implemented."))
}
return nil
}
@@ -694,7 +708,7 @@ func (s *apiRPCServer) DeleteUser(args *Z_DeleteUserArgs, returns *Z_DeleteUserR
}); ok {
returns.A = hook.DeleteUser(args.A)
} else {
return fmt.Errorf("API DeleteUser called but not implemented.")
return encodableError(fmt.Errorf("API DeleteUser called but not implemented."))
}
return nil
}
@@ -723,7 +737,7 @@ func (s *apiRPCServer) GetUser(args *Z_GetUserArgs, returns *Z_GetUserReturns) e
}); ok {
returns.A, returns.B = hook.GetUser(args.A)
} else {
return fmt.Errorf("API GetUser called but not implemented.")
return encodableError(fmt.Errorf("API GetUser called but not implemented."))
}
return nil
}
@@ -752,7 +766,7 @@ func (s *apiRPCServer) GetUserByEmail(args *Z_GetUserByEmailArgs, returns *Z_Get
}); ok {
returns.A, returns.B = hook.GetUserByEmail(args.A)
} else {
return fmt.Errorf("API GetUserByEmail called but not implemented.")
return encodableError(fmt.Errorf("API GetUserByEmail called but not implemented."))
}
return nil
}
@@ -781,7 +795,7 @@ func (s *apiRPCServer) GetUserByUsername(args *Z_GetUserByUsernameArgs, returns
}); ok {
returns.A, returns.B = hook.GetUserByUsername(args.A)
} else {
return fmt.Errorf("API GetUserByUsername called but not implemented.")
return encodableError(fmt.Errorf("API GetUserByUsername called but not implemented."))
}
return nil
}
@@ -810,7 +824,7 @@ func (s *apiRPCServer) UpdateUser(args *Z_UpdateUserArgs, returns *Z_UpdateUserR
}); ok {
returns.A, returns.B = hook.UpdateUser(args.A)
} else {
return fmt.Errorf("API UpdateUser called but not implemented.")
return encodableError(fmt.Errorf("API UpdateUser called but not implemented."))
}
return nil
}
@@ -839,7 +853,7 @@ func (s *apiRPCServer) GetUserStatus(args *Z_GetUserStatusArgs, returns *Z_GetUs
}); ok {
returns.A, returns.B = hook.GetUserStatus(args.A)
} else {
return fmt.Errorf("API GetUserStatus called but not implemented.")
return encodableError(fmt.Errorf("API GetUserStatus called but not implemented."))
}
return nil
}
@@ -868,7 +882,7 @@ func (s *apiRPCServer) GetUserStatusesByIds(args *Z_GetUserStatusesByIdsArgs, re
}); ok {
returns.A, returns.B = hook.GetUserStatusesByIds(args.A)
} else {
return fmt.Errorf("API GetUserStatusesByIds called but not implemented.")
return encodableError(fmt.Errorf("API GetUserStatusesByIds called but not implemented."))
}
return nil
}
@@ -898,7 +912,7 @@ func (s *apiRPCServer) UpdateUserStatus(args *Z_UpdateUserStatusArgs, returns *Z
}); ok {
returns.A, returns.B = hook.UpdateUserStatus(args.A, args.B)
} else {
return fmt.Errorf("API UpdateUserStatus called but not implemented.")
return encodableError(fmt.Errorf("API UpdateUserStatus called but not implemented."))
}
return nil
}
@@ -928,7 +942,7 @@ func (s *apiRPCServer) GetLDAPUserAttributes(args *Z_GetLDAPUserAttributesArgs,
}); ok {
returns.A, returns.B = hook.GetLDAPUserAttributes(args.A, args.B)
} else {
return fmt.Errorf("API GetLDAPUserAttributes called but not implemented.")
return encodableError(fmt.Errorf("API GetLDAPUserAttributes called but not implemented."))
}
return nil
}
@@ -957,7 +971,7 @@ func (s *apiRPCServer) CreateTeam(args *Z_CreateTeamArgs, returns *Z_CreateTeamR
}); ok {
returns.A, returns.B = hook.CreateTeam(args.A)
} else {
return fmt.Errorf("API CreateTeam called but not implemented.")
return encodableError(fmt.Errorf("API CreateTeam called but not implemented."))
}
return nil
}
@@ -985,7 +999,7 @@ func (s *apiRPCServer) DeleteTeam(args *Z_DeleteTeamArgs, returns *Z_DeleteTeamR
}); ok {
returns.A = hook.DeleteTeam(args.A)
} else {
return fmt.Errorf("API DeleteTeam called but not implemented.")
return encodableError(fmt.Errorf("API DeleteTeam called but not implemented."))
}
return nil
}
@@ -1013,7 +1027,7 @@ func (s *apiRPCServer) GetTeams(args *Z_GetTeamsArgs, returns *Z_GetTeamsReturns
}); ok {
returns.A, returns.B = hook.GetTeams()
} else {
return fmt.Errorf("API GetTeams called but not implemented.")
return encodableError(fmt.Errorf("API GetTeams called but not implemented."))
}
return nil
}
@@ -1042,7 +1056,7 @@ func (s *apiRPCServer) GetTeam(args *Z_GetTeamArgs, returns *Z_GetTeamReturns) e
}); ok {
returns.A, returns.B = hook.GetTeam(args.A)
} else {
return fmt.Errorf("API GetTeam called but not implemented.")
return encodableError(fmt.Errorf("API GetTeam called but not implemented."))
}
return nil
}
@@ -1071,7 +1085,7 @@ func (s *apiRPCServer) GetTeamByName(args *Z_GetTeamByNameArgs, returns *Z_GetTe
}); ok {
returns.A, returns.B = hook.GetTeamByName(args.A)
} else {
return fmt.Errorf("API GetTeamByName called but not implemented.")
return encodableError(fmt.Errorf("API GetTeamByName called but not implemented."))
}
return nil
}
@@ -1100,7 +1114,7 @@ func (s *apiRPCServer) UpdateTeam(args *Z_UpdateTeamArgs, returns *Z_UpdateTeamR
}); ok {
returns.A, returns.B = hook.UpdateTeam(args.A)
} else {
return fmt.Errorf("API UpdateTeam called but not implemented.")
return encodableError(fmt.Errorf("API UpdateTeam called but not implemented."))
}
return nil
}
@@ -1130,7 +1144,7 @@ func (s *apiRPCServer) CreateTeamMember(args *Z_CreateTeamMemberArgs, returns *Z
}); ok {
returns.A, returns.B = hook.CreateTeamMember(args.A, args.B)
} else {
return fmt.Errorf("API CreateTeamMember called but not implemented.")
return encodableError(fmt.Errorf("API CreateTeamMember called but not implemented."))
}
return nil
}
@@ -1161,7 +1175,7 @@ func (s *apiRPCServer) CreateTeamMembers(args *Z_CreateTeamMembersArgs, returns
}); ok {
returns.A, returns.B = hook.CreateTeamMembers(args.A, args.B, args.C)
} else {
return fmt.Errorf("API CreateTeamMembers called but not implemented.")
return encodableError(fmt.Errorf("API CreateTeamMembers called but not implemented."))
}
return nil
}
@@ -1191,7 +1205,7 @@ func (s *apiRPCServer) DeleteTeamMember(args *Z_DeleteTeamMemberArgs, returns *Z
}); ok {
returns.A = hook.DeleteTeamMember(args.A, args.B, args.C)
} else {
return fmt.Errorf("API DeleteTeamMember called but not implemented.")
return encodableError(fmt.Errorf("API DeleteTeamMember called but not implemented."))
}
return nil
}
@@ -1222,7 +1236,7 @@ func (s *apiRPCServer) GetTeamMembers(args *Z_GetTeamMembersArgs, returns *Z_Get
}); ok {
returns.A, returns.B = hook.GetTeamMembers(args.A, args.B, args.C)
} else {
return fmt.Errorf("API GetTeamMembers called but not implemented.")
return encodableError(fmt.Errorf("API GetTeamMembers called but not implemented."))
}
return nil
}
@@ -1252,7 +1266,7 @@ func (s *apiRPCServer) GetTeamMember(args *Z_GetTeamMemberArgs, returns *Z_GetTe
}); ok {
returns.A, returns.B = hook.GetTeamMember(args.A, args.B)
} else {
return fmt.Errorf("API GetTeamMember called but not implemented.")
return encodableError(fmt.Errorf("API GetTeamMember called but not implemented."))
}
return nil
}
@@ -1283,7 +1297,7 @@ func (s *apiRPCServer) UpdateTeamMemberRoles(args *Z_UpdateTeamMemberRolesArgs,
}); ok {
returns.A, returns.B = hook.UpdateTeamMemberRoles(args.A, args.B, args.C)
} else {
return fmt.Errorf("API UpdateTeamMemberRoles called but not implemented.")
return encodableError(fmt.Errorf("API UpdateTeamMemberRoles called but not implemented."))
}
return nil
}
@@ -1312,7 +1326,7 @@ func (s *apiRPCServer) CreateChannel(args *Z_CreateChannelArgs, returns *Z_Creat
}); ok {
returns.A, returns.B = hook.CreateChannel(args.A)
} else {
return fmt.Errorf("API CreateChannel called but not implemented.")
return encodableError(fmt.Errorf("API CreateChannel called but not implemented."))
}
return nil
}
@@ -1340,7 +1354,7 @@ func (s *apiRPCServer) DeleteChannel(args *Z_DeleteChannelArgs, returns *Z_Delet
}); ok {
returns.A = hook.DeleteChannel(args.A)
} else {
return fmt.Errorf("API DeleteChannel called but not implemented.")
return encodableError(fmt.Errorf("API DeleteChannel called but not implemented."))
}
return nil
}
@@ -1371,7 +1385,7 @@ func (s *apiRPCServer) GetPublicChannelsForTeam(args *Z_GetPublicChannelsForTeam
}); ok {
returns.A, returns.B = hook.GetPublicChannelsForTeam(args.A, args.B, args.C)
} else {
return fmt.Errorf("API GetPublicChannelsForTeam called but not implemented.")
return encodableError(fmt.Errorf("API GetPublicChannelsForTeam called but not implemented."))
}
return nil
}
@@ -1400,7 +1414,7 @@ func (s *apiRPCServer) GetChannel(args *Z_GetChannelArgs, returns *Z_GetChannelR
}); ok {
returns.A, returns.B = hook.GetChannel(args.A)
} else {
return fmt.Errorf("API GetChannel called but not implemented.")
return encodableError(fmt.Errorf("API GetChannel called but not implemented."))
}
return nil
}
@@ -1431,7 +1445,7 @@ func (s *apiRPCServer) GetChannelByName(args *Z_GetChannelByNameArgs, returns *Z
}); ok {
returns.A, returns.B = hook.GetChannelByName(args.A, args.B, args.C)
} else {
return fmt.Errorf("API GetChannelByName called but not implemented.")
return encodableError(fmt.Errorf("API GetChannelByName called but not implemented."))
}
return nil
}
@@ -1462,7 +1476,7 @@ func (s *apiRPCServer) GetChannelByNameForTeamName(args *Z_GetChannelByNameForTe
}); ok {
returns.A, returns.B = hook.GetChannelByNameForTeamName(args.A, args.B, args.C)
} else {
return fmt.Errorf("API GetChannelByNameForTeamName called but not implemented.")
return encodableError(fmt.Errorf("API GetChannelByNameForTeamName called but not implemented."))
}
return nil
}
@@ -1492,7 +1506,7 @@ func (s *apiRPCServer) GetDirectChannel(args *Z_GetDirectChannelArgs, returns *Z
}); ok {
returns.A, returns.B = hook.GetDirectChannel(args.A, args.B)
} else {
return fmt.Errorf("API GetDirectChannel called but not implemented.")
return encodableError(fmt.Errorf("API GetDirectChannel called but not implemented."))
}
return nil
}
@@ -1521,7 +1535,7 @@ func (s *apiRPCServer) GetGroupChannel(args *Z_GetGroupChannelArgs, returns *Z_G
}); ok {
returns.A, returns.B = hook.GetGroupChannel(args.A)
} else {
return fmt.Errorf("API GetGroupChannel called but not implemented.")
return encodableError(fmt.Errorf("API GetGroupChannel called but not implemented."))
}
return nil
}
@@ -1550,7 +1564,7 @@ func (s *apiRPCServer) UpdateChannel(args *Z_UpdateChannelArgs, returns *Z_Updat
}); ok {
returns.A, returns.B = hook.UpdateChannel(args.A)
} else {
return fmt.Errorf("API UpdateChannel called but not implemented.")
return encodableError(fmt.Errorf("API UpdateChannel called but not implemented."))
}
return nil
}
@@ -1580,7 +1594,7 @@ func (s *apiRPCServer) AddChannelMember(args *Z_AddChannelMemberArgs, returns *Z
}); ok {
returns.A, returns.B = hook.AddChannelMember(args.A, args.B)
} else {
return fmt.Errorf("API AddChannelMember called but not implemented.")
return encodableError(fmt.Errorf("API AddChannelMember called but not implemented."))
}
return nil
}
@@ -1610,7 +1624,7 @@ func (s *apiRPCServer) GetChannelMember(args *Z_GetChannelMemberArgs, returns *Z
}); ok {
returns.A, returns.B = hook.GetChannelMember(args.A, args.B)
} else {
return fmt.Errorf("API GetChannelMember called but not implemented.")
return encodableError(fmt.Errorf("API GetChannelMember called but not implemented."))
}
return nil
}
@@ -1641,7 +1655,7 @@ func (s *apiRPCServer) UpdateChannelMemberRoles(args *Z_UpdateChannelMemberRoles
}); ok {
returns.A, returns.B = hook.UpdateChannelMemberRoles(args.A, args.B, args.C)
} else {
return fmt.Errorf("API UpdateChannelMemberRoles called but not implemented.")
return encodableError(fmt.Errorf("API UpdateChannelMemberRoles called but not implemented."))
}
return nil
}
@@ -1672,7 +1686,7 @@ func (s *apiRPCServer) UpdateChannelMemberNotifications(args *Z_UpdateChannelMem
}); ok {
returns.A, returns.B = hook.UpdateChannelMemberNotifications(args.A, args.B, args.C)
} else {
return fmt.Errorf("API UpdateChannelMemberNotifications called but not implemented.")
return encodableError(fmt.Errorf("API UpdateChannelMemberNotifications called but not implemented."))
}
return nil
}
@@ -1701,7 +1715,7 @@ func (s *apiRPCServer) DeleteChannelMember(args *Z_DeleteChannelMemberArgs, retu
}); ok {
returns.A = hook.DeleteChannelMember(args.A, args.B)
} else {
return fmt.Errorf("API DeleteChannelMember called but not implemented.")
return encodableError(fmt.Errorf("API DeleteChannelMember called but not implemented."))
}
return nil
}
@@ -1730,7 +1744,7 @@ func (s *apiRPCServer) CreatePost(args *Z_CreatePostArgs, returns *Z_CreatePostR
}); ok {
returns.A, returns.B = hook.CreatePost(args.A)
} else {
return fmt.Errorf("API CreatePost called but not implemented.")
return encodableError(fmt.Errorf("API CreatePost called but not implemented."))
}
return nil
}
@@ -1759,7 +1773,7 @@ func (s *apiRPCServer) AddReaction(args *Z_AddReactionArgs, returns *Z_AddReacti
}); ok {
returns.A, returns.B = hook.AddReaction(args.A)
} else {
return fmt.Errorf("API AddReaction called but not implemented.")
return encodableError(fmt.Errorf("API AddReaction called but not implemented."))
}
return nil
}
@@ -1787,7 +1801,7 @@ func (s *apiRPCServer) RemoveReaction(args *Z_RemoveReactionArgs, returns *Z_Rem
}); ok {
returns.A = hook.RemoveReaction(args.A)
} else {
return fmt.Errorf("API RemoveReaction called but not implemented.")
return encodableError(fmt.Errorf("API RemoveReaction called but not implemented."))
}
return nil
}
@@ -1816,7 +1830,7 @@ func (s *apiRPCServer) GetReactions(args *Z_GetReactionsArgs, returns *Z_GetReac
}); ok {
returns.A, returns.B = hook.GetReactions(args.A)
} else {
return fmt.Errorf("API GetReactions called but not implemented.")
return encodableError(fmt.Errorf("API GetReactions called but not implemented."))
}
return nil
}
@@ -1845,7 +1859,7 @@ func (s *apiRPCServer) SendEphemeralPost(args *Z_SendEphemeralPostArgs, returns
}); ok {
returns.A = hook.SendEphemeralPost(args.A, args.B)
} else {
return fmt.Errorf("API SendEphemeralPost called but not implemented.")
return encodableError(fmt.Errorf("API SendEphemeralPost called but not implemented."))
}
return nil
}
@@ -1873,7 +1887,7 @@ func (s *apiRPCServer) DeletePost(args *Z_DeletePostArgs, returns *Z_DeletePostR
}); ok {
returns.A = hook.DeletePost(args.A)
} else {
return fmt.Errorf("API DeletePost called but not implemented.")
return encodableError(fmt.Errorf("API DeletePost called but not implemented."))
}
return nil
}
@@ -1902,7 +1916,7 @@ func (s *apiRPCServer) GetPost(args *Z_GetPostArgs, returns *Z_GetPostReturns) e
}); ok {
returns.A, returns.B = hook.GetPost(args.A)
} else {
return fmt.Errorf("API GetPost called but not implemented.")
return encodableError(fmt.Errorf("API GetPost called but not implemented."))
}
return nil
}
@@ -1931,7 +1945,7 @@ func (s *apiRPCServer) UpdatePost(args *Z_UpdatePostArgs, returns *Z_UpdatePostR
}); ok {
returns.A, returns.B = hook.UpdatePost(args.A)
} else {
return fmt.Errorf("API UpdatePost called but not implemented.")
return encodableError(fmt.Errorf("API UpdatePost called but not implemented."))
}
return nil
}
@@ -1961,7 +1975,7 @@ func (s *apiRPCServer) CopyFileInfos(args *Z_CopyFileInfosArgs, returns *Z_CopyF
}); ok {
returns.A, returns.B = hook.CopyFileInfos(args.A, args.B)
} else {
return fmt.Errorf("API CopyFileInfos called but not implemented.")
return encodableError(fmt.Errorf("API CopyFileInfos called but not implemented."))
}
return nil
}
@@ -1990,7 +2004,7 @@ func (s *apiRPCServer) GetFileInfo(args *Z_GetFileInfoArgs, returns *Z_GetFileIn
}); ok {
returns.A, returns.B = hook.GetFileInfo(args.A)
} else {
return fmt.Errorf("API GetFileInfo called but not implemented.")
return encodableError(fmt.Errorf("API GetFileInfo called but not implemented."))
}
return nil
}
@@ -2019,7 +2033,7 @@ func (s *apiRPCServer) ReadFile(args *Z_ReadFileArgs, returns *Z_ReadFileReturns
}); ok {
returns.A, returns.B = hook.ReadFile(args.A)
} else {
return fmt.Errorf("API ReadFile called but not implemented.")
return encodableError(fmt.Errorf("API ReadFile called but not implemented."))
}
return nil
}
@@ -2048,7 +2062,7 @@ func (s *apiRPCServer) KVSet(args *Z_KVSetArgs, returns *Z_KVSetReturns) error {
}); ok {
returns.A = hook.KVSet(args.A, args.B)
} else {
return fmt.Errorf("API KVSet called but not implemented.")
return encodableError(fmt.Errorf("API KVSet called but not implemented."))
}
return nil
}
@@ -2077,7 +2091,7 @@ func (s *apiRPCServer) KVGet(args *Z_KVGetArgs, returns *Z_KVGetReturns) error {
}); ok {
returns.A, returns.B = hook.KVGet(args.A)
} else {
return fmt.Errorf("API KVGet called but not implemented.")
return encodableError(fmt.Errorf("API KVGet called but not implemented."))
}
return nil
}
@@ -2105,7 +2119,7 @@ func (s *apiRPCServer) KVDelete(args *Z_KVDeleteArgs, returns *Z_KVDeleteReturns
}); ok {
returns.A = hook.KVDelete(args.A)
} else {
return fmt.Errorf("API KVDelete called but not implemented.")
return encodableError(fmt.Errorf("API KVDelete called but not implemented."))
}
return nil
}
@@ -2134,7 +2148,7 @@ func (s *apiRPCServer) PublishWebSocketEvent(args *Z_PublishWebSocketEventArgs,
}); ok {
hook.PublishWebSocketEvent(args.A, args.B, args.C)
} else {
return fmt.Errorf("API PublishWebSocketEvent called but not implemented.")
return encodableError(fmt.Errorf("API PublishWebSocketEvent called but not implemented."))
}
return nil
}
@@ -2163,7 +2177,7 @@ func (s *apiRPCServer) HasPermissionTo(args *Z_HasPermissionToArgs, returns *Z_H
}); ok {
returns.A = hook.HasPermissionTo(args.A, args.B)
} else {
return fmt.Errorf("API HasPermissionTo called but not implemented.")
return encodableError(fmt.Errorf("API HasPermissionTo called but not implemented."))
}
return nil
}
@@ -2193,7 +2207,7 @@ func (s *apiRPCServer) HasPermissionToTeam(args *Z_HasPermissionToTeamArgs, retu
}); ok {
returns.A = hook.HasPermissionToTeam(args.A, args.B, args.C)
} else {
return fmt.Errorf("API HasPermissionToTeam called but not implemented.")
return encodableError(fmt.Errorf("API HasPermissionToTeam called but not implemented."))
}
return nil
}
@@ -2223,7 +2237,7 @@ func (s *apiRPCServer) HasPermissionToChannel(args *Z_HasPermissionToChannelArgs
}); ok {
returns.A = hook.HasPermissionToChannel(args.A, args.B, args.C)
} else {
return fmt.Errorf("API HasPermissionToChannel called but not implemented.")
return encodableError(fmt.Errorf("API HasPermissionToChannel called but not implemented."))
}
return nil
}
@@ -2251,7 +2265,7 @@ func (s *apiRPCServer) LogDebug(args *Z_LogDebugArgs, returns *Z_LogDebugReturns
}); ok {
hook.LogDebug(args.A, args.B...)
} else {
return fmt.Errorf("API LogDebug called but not implemented.")
return encodableError(fmt.Errorf("API LogDebug called but not implemented."))
}
return nil
}
@@ -2279,7 +2293,7 @@ func (s *apiRPCServer) LogInfo(args *Z_LogInfoArgs, returns *Z_LogInfoReturns) e
}); ok {
hook.LogInfo(args.A, args.B...)
} else {
return fmt.Errorf("API LogInfo called but not implemented.")
return encodableError(fmt.Errorf("API LogInfo called but not implemented."))
}
return nil
}
@@ -2307,7 +2321,7 @@ func (s *apiRPCServer) LogError(args *Z_LogErrorArgs, returns *Z_LogErrorReturns
}); ok {
hook.LogError(args.A, args.B...)
} else {
return fmt.Errorf("API LogError called but not implemented.")
return encodableError(fmt.Errorf("API LogError called but not implemented."))
}
return nil
}
@@ -2335,7 +2349,7 @@ func (s *apiRPCServer) LogWarn(args *Z_LogWarnArgs, returns *Z_LogWarnReturns) e
}); ok {
hook.LogWarn(args.A, args.B...)
} else {
return fmt.Errorf("API LogWarn called but not implemented.")
return encodableError(fmt.Errorf("API LogWarn called but not implemented."))
}
return nil
}

Просмотреть файл

@@ -69,6 +69,43 @@ func FieldListToNames(fieldList *ast.FieldList, fileset *token.FileSet) string {
return strings.Join(result, ", ")
}
func FieldListToEncodedErrors(structPrefix string, fieldList *ast.FieldList, fileset *token.FileSet) string {
result := []string{}
if fieldList == nil {
return ""
}
nextLetter := 'A'
for _, field := range fieldList.List {
typeNameBuffer := &bytes.Buffer{}
err := printer.Fprint(typeNameBuffer, fileset, field.Type)
if err != nil {
panic(err)
}
if typeNameBuffer.String() != "error" {
nextLetter += 1
continue
}
name := ""
if len(field.Names) == 0 {
name = string(nextLetter)
nextLetter += 1
} else {
for range field.Names {
name += string(nextLetter)
nextLetter += 1
}
}
result = append(result, structPrefix+name+" = encodableError("+structPrefix+name+")")
}
return strings.Join(result, "\n")
}
func FieldListDestruct(structPrefix string, fieldList *ast.FieldList, fileset *token.FileSet) string {
result := []string{}
if fieldList == nil || len(fieldList.List) == 0 {
@@ -237,8 +274,9 @@ func (s *hooksRPCServer) {{.Name}}(args *{{.Name | obscure}}Args, returns *{{.Na
{{.Name}}{{funcStyle .Params}} {{funcStyle .Return}}
}); ok {
{{if .Return}}{{destruct "returns." .Return}} = {{end}}hook.{{.Name}}({{destruct "args." .Params}})
{{if .Return}}{{encodeErrors "returns." .Return}}{{end}}
} else {
return fmt.Errorf("Hook {{.Name}} called but not implemented.")
return encodableError(fmt.Errorf("Hook {{.Name}} called but not implemented."))
}
return nil
}
@@ -269,7 +307,7 @@ func (s *apiRPCServer) {{.Name}}(args *{{.Name | obscure}}Args, returns *{{.Name
}); ok {
{{if .Return}}{{destruct "returns." .Return}} = {{end}}hook.{{.Name}}({{destruct "args." .Params}})
} else {
return fmt.Errorf("API {{.Name}} called but not implemented.")
return encodableError(fmt.Errorf("API {{.Name}} called but not implemented."))
}
return nil
}
@@ -292,6 +330,9 @@ func generateGlue(info *PluginInterfaceInfo) {
"funcStyle": func(fields *ast.FieldList) string { return FieldListToFuncList(fields, info.FileSet) },
"structStyle": func(fields *ast.FieldList) string { return FieldListToStructList(fields, info.FileSet) },
"valuesOnly": func(fields *ast.FieldList) string { return FieldListToNames(fields, info.FileSet) },
"encodeErrors": func(structPrefix string, fields *ast.FieldList) string {
return FieldListToEncodedErrors(structPrefix, fields, info.FileSet)
},
"destruct": func(structPrefix string, fields *ast.FieldList) string {
return FieldListDestruct(structPrefix, fields, info.FileSet)
},