From f2ddef9117712508234b85583c240cc856141980 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Thu, 13 Sep 2018 14:31:22 -0400 Subject: 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 --- plugin/client_rpc.go | 31 ++++++- plugin/client_rpc_generated.go | 168 ++++++++++++++++++++----------------- plugin/interface_generator/main.go | 45 +++++++++- 3 files changed, 163 insertions(+), 81 deletions(-) (limited to 'plugin') diff --git a/plugin/client_rpc.go b/plugin/client_rpc.go index d8547f352..72bd41f68 100644 --- a/plugin/client_rpc.go +++ b/plugin/client_rpc.go @@ -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 } diff --git a/plugin/client_rpc_generated.go b/plugin/client_rpc_generated.go index 9cebda716..1403e3ff2 100644 --- a/plugin/client_rpc_generated.go +++ b/plugin/client_rpc_generated.go @@ -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 } diff --git a/plugin/interface_generator/main.go b/plugin/interface_generator/main.go index 6aa8bdfb1..95977713e 100644 --- a/plugin/interface_generator/main.go +++ b/plugin/interface_generator/main.go @@ -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) }, -- cgit v1.2.3-1-g7c22