Makpoc/gomigen

Add ability to stop wrapped method invocation

Opened this issue · 0 comments

Hi,

First of all thanks for your awesome work.

I'm trying to use gomigen for a project at work. I have an audit logging layer on my services that records every operation in a database. Since the code is mostly the same for all methods I'd like to use a code generation tool. However, I'm not able to use gomigen, since there is no option to stop the invocation of the original method. I need to do this if persisting the audit log in the database fails.

Here's how the current implementation looks (I've stripped some details):

func (s *Service) Operation(ctx context.Context, p *Params) (*Result, error) {
	user, err := auth.UserFromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("no user info provided: %w", err)
	}

	ri, err := remoteinfo.FromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("error extracting remote info: %w", err)
	}

	log, err := s.logger.Start(ctx, &audit.Log{
		UserID:    user.ID,
		ClientID:  user.ClientID,
		Action:    "package.Service.Operation",
		Params:    p,
		UserAgent: ri.UserAgent,
		RemoteIP:  ri.RemoteIP,
		Country:   ri.Country,
	})

	if err != nil {
		// In this scenario I need to stop the invocation of the original Operation method.
		return nil, fmt.Errorf("error persisting start audit log: %w", err)
	}

	ctx = audit.LogInContext(ctx, log)
	r, err := s.next.Operation(ctx, p)

	// We're fine with sacrificing info populated on end.
	_ = s.logger.End(ctx, log)

	return r, err
}

The types.MethodInfo object contains almost all necessary information to switch the above implementation to Hooks. It only lacks the parameters of the method, but I'll open a separate feature request for this.

Have you considered implementing a mechanism that will stop the original method from being invoked? Perhaps if the OnEntry method returns an (specific?) error this could do the trick. However I don't know whether this fits in the general design idea of gomigen.

Thanks,
Ivan