From ae8a11ef9947fd7aeda336adf3f382177cb7d548 Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Mon, 8 Jun 2026 14:18:49 +0530 Subject: [PATCH 1/7] refactor(api): pass real errors in CodeInternal, remove redundant errorLogger calls --- internal/api/v1beta1connect/audit_record.go | 10 +- .../api/v1beta1connect/audit_record_test.go | 2 +- internal/api/v1beta1connect/authenticate.go | 53 ++---- internal/api/v1beta1connect/authorize.go | 12 +- internal/api/v1beta1connect/billing_check.go | 29 +--- .../api/v1beta1connect/billing_check_test.go | 8 +- .../api/v1beta1connect/billing_checkout.go | 59 ++----- .../v1beta1connect/billing_checkout_test.go | 14 +- .../api/v1beta1connect/billing_customer.go | 111 +++--------- .../v1beta1connect/billing_customer_test.go | 3 +- .../api/v1beta1connect/billing_invoice.go | 38 ++-- .../v1beta1connect/billing_invoice_test.go | 8 +- internal/api/v1beta1connect/billing_plan.go | 34 +--- .../api/v1beta1connect/billing_plan_test.go | 12 +- .../api/v1beta1connect/billing_product.go | 92 +++------- .../v1beta1connect/billing_product_test.go | 20 +-- .../v1beta1connect/billing_subscription.go | 46 ++--- internal/api/v1beta1connect/billing_usage.go | 57 ++---- .../api/v1beta1connect/billing_usage_test.go | 6 +- .../api/v1beta1connect/billing_webhook.go | 7 +- .../v1beta1connect/billing_webhook_test.go | 2 +- internal/api/v1beta1connect/deleter.go | 13 +- internal/api/v1beta1connect/deleter_test.go | 5 +- internal/api/v1beta1connect/domain.go | 71 ++------ internal/api/v1beta1connect/domain_test.go | 23 +-- internal/api/v1beta1connect/group.go | 158 ++++------------- internal/api/v1beta1connect/group_test.go | 23 +-- internal/api/v1beta1connect/invitations.go | 90 +++------- .../api/v1beta1connect/invitations_test.go | 17 +- internal/api/v1beta1connect/kyc.go | 20 +-- internal/api/v1beta1connect/kyc_test.go | 5 +- internal/api/v1beta1connect/metaschema.go | 31 +--- .../api/v1beta1connect/metaschema_test.go | 7 +- internal/api/v1beta1connect/namespace.go | 18 +- internal/api/v1beta1connect/namespace_test.go | 5 +- internal/api/v1beta1connect/organization.go | 137 ++++----------- .../v1beta1connect/organization_billing.go | 10 +- .../v1beta1connect/organization_invoices.go | 6 +- .../api/v1beta1connect/organization_pats.go | 6 +- .../v1beta1connect/organization_pats_test.go | 2 +- .../v1beta1connect/organization_projects.go | 12 +- .../organization_serviceuser.go | 6 +- .../organization_serviceuser_credentials.go | 6 +- .../api/v1beta1connect/organization_test.go | 31 ++-- .../api/v1beta1connect/organization_tokens.go | 12 +- .../api/v1beta1connect/organization_users.go | 14 +- internal/api/v1beta1connect/permission.go | 36 ++-- .../api/v1beta1connect/permission_check.go | 13 +- .../v1beta1connect/permission_check_test.go | 3 +- .../api/v1beta1connect/permission_test.go | 17 +- internal/api/v1beta1connect/platform.go | 40 ++--- internal/api/v1beta1connect/policy.go | 41 +---- internal/api/v1beta1connect/preferences.go | 3 +- .../api/v1beta1connect/preferences_test.go | 11 +- internal/api/v1beta1connect/project.go | 74 +++----- internal/api/v1beta1connect/project_test.go | 17 +- internal/api/v1beta1connect/project_users.go | 4 +- internal/api/v1beta1connect/prospect.go | 43 ++--- internal/api/v1beta1connect/prospect_test.go | 7 +- internal/api/v1beta1connect/relation.go | 33 +--- internal/api/v1beta1connect/relation_test.go | 9 +- internal/api/v1beta1connect/resource.go | 71 ++------ internal/api/v1beta1connect/resource_test.go | 75 +++++--- internal/api/v1beta1connect/role.go | 86 ++------- internal/api/v1beta1connect/role_test.go | 5 +- internal/api/v1beta1connect/serviceuser.go | 101 +++-------- .../api/v1beta1connect/serviceuser_test.go | 24 +-- internal/api/v1beta1connect/session.go | 38 +--- internal/api/v1beta1connect/user.go | 164 +++++------------- internal/api/v1beta1connect/user_orgs.go | 4 +- internal/api/v1beta1connect/user_pat.go | 5 +- internal/api/v1beta1connect/user_pat_test.go | 16 +- internal/api/v1beta1connect/user_projects.go | 5 +- internal/api/v1beta1connect/user_test.go | 3 +- internal/api/v1beta1connect/v1beta1connect.go | 11 +- internal/api/v1beta1connect/webhook.go | 32 +--- 76 files changed, 673 insertions(+), 1669 deletions(-) diff --git a/internal/api/v1beta1connect/audit_record.go b/internal/api/v1beta1connect/audit_record.go index f76f636bc..20d7b260f 100644 --- a/internal/api/v1beta1connect/audit_record.go +++ b/internal/api/v1beta1connect/audit_record.go @@ -131,8 +131,7 @@ func (h *ConnectHandler) ListAuditRecords(ctx context.Context, request *connect. case errors.Is(err, auditrecord.ErrNotFound): return nil, connect.NewError(connect.CodeNotFound, err) default: - errorLogger.LogUnexpectedError(ctx, request, "ListAuditRecords", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAuditRecords: %w", err)) } } pbRecords := make([]*frontierv1beta1.AuditRecord, 0) @@ -191,8 +190,7 @@ func (h *ConnectHandler) ExportAuditRecords(ctx context.Context, request *connec case errors.Is(err, auditrecord.ErrNotFound): return connect.NewError(connect.CodeNotFound, err) default: - errorLogger.LogUnexpectedError(ctx, request, "ExportAuditRecords", err) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("ExportAuditRecords: %w", err)) } } // Stream the data using io.Reader @@ -273,7 +271,7 @@ func streamReaderInChunks(reader io.Reader, contentType string, stream *connect. break } if err != nil { - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("streamReaderInChunks: %w", err)) } if n > 0 { msg := &httpbody.HttpBody{ @@ -281,7 +279,7 @@ func streamReaderInChunks(reader io.Reader, contentType string, stream *connect. Data: buffer[:n], } if sendErr := stream.Send(msg); sendErr != nil { - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("streamReaderInChunks: %w", sendErr)) } } } diff --git a/internal/api/v1beta1connect/audit_record_test.go b/internal/api/v1beta1connect/audit_record_test.go index 482338bf8..0fa88df23 100644 --- a/internal/api/v1beta1connect/audit_record_test.go +++ b/internal/api/v1beta1connect/audit_record_test.go @@ -1449,7 +1449,7 @@ func TestHandler_ListAuditRecords(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, errors.New("database connection failed")), }, { name: "should return invalid argument error for bad input", diff --git a/internal/api/v1beta1connect/authenticate.go b/internal/api/v1beta1connect/authenticate.go index f55761d65..06d5aed14 100644 --- a/internal/api/v1beta1connect/authenticate.go +++ b/internal/api/v1beta1connect/authenticate.go @@ -26,8 +26,6 @@ import ( ) func (h *ConnectHandler) Authenticate(ctx context.Context, request *connect.Request[frontierv1beta1.AuthenticateRequest]) (*connect.Response[frontierv1beta1.AuthenticateResponse], error) { - errorLogger := NewErrorLogger() - returnToURL := h.authnService.SanitizeReturnToURL(request.Msg.GetReturnTo()) callbackURL := h.authnService.SanitizeCallbackURL(request.Msg.GetCallbackUrl()) @@ -41,8 +39,7 @@ func (h *ConnectHandler) Authenticate(ctx context.Context, request *connect.Requ } return resp, nil } else if err != nil && !errors.Is(err, frontiersession.ErrNoSession) { - errorLogger.LogUnexpectedError(ctx, request, "Authenticate", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("Authenticate: %w", err)) } if (request.Msg.GetStrategyName() == authenticate.MailLinkAuthMethod.String() || request.Msg.GetStrategyName() == authenticate.MailOTPAuthMethod.String()) && !isValidEmail(request.Msg.GetEmail()) { @@ -57,10 +54,7 @@ func (h *ConnectHandler) Authenticate(ctx context.Context, request *connect.Requ Email: request.Msg.GetEmail(), }) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "Authenticate", err, - "strategy", request.Msg.GetStrategyName(), - "email", request.Msg.GetEmail()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("Authenticate: strategy=%s email=%s: %w", request.Msg.GetStrategyName(), request.Msg.GetEmail(), err)) } // set location header for redirect to start auth? @@ -76,16 +70,12 @@ func (h *ConnectHandler) Authenticate(ctx context.Context, request *connect.Requ if request.Msg.GetStrategyName() == authenticate.PassKeyAuthMethod.String() { userCredentils := &structpb.Value{} if err = userCredentils.UnmarshalJSON(response.StateConfig["options"].([]byte)); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "Authenticate", err, - "strategy", authenticate.PassKeyAuthMethod.String()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("Authenticate: strategy=%s: %w", authenticate.PassKeyAuthMethod.String(), err)) } typeValue, ok := response.Flow.Metadata["passkey_type"].(string) if !ok { err = fmt.Errorf("passkey_type metadata is not a string") - errorLogger.LogUnexpectedError(ctx, request, "Authenticate", err, - "strategy", authenticate.PassKeyAuthMethod.String()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("Authenticate: strategy=%s: %w", authenticate.PassKeyAuthMethod.String(), err)) } stringValue := &structpb.Value{ Kind: &structpb.Value_StringValue{ @@ -123,10 +113,7 @@ func (h *ConnectHandler) AuthCallback(ctx context.Context, request *connect.Requ "state", request.Msg.GetState()) return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogUnexpectedError(ctx, request, "AuthCallback", err, - "strategy", request.Msg.GetStrategyName(), - "state", request.Msg.GetState()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AuthCallback: strategy=%s state=%s: %w", request.Msg.GetStrategyName(), request.Msg.GetState(), err)) } // Extract session metadata from request headers @@ -135,9 +122,7 @@ func (h *ConnectHandler) AuthCallback(ctx context.Context, request *connect.Requ // registration/login complete, build a session session, err := h.sessionService.Create(ctx, response.User.ID, sessionMetadata) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "AuthCallback", err, - "user_id", response.User.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AuthCallback: user_id=%s: %w", response.User.ID, err)) } // create response and set headers resp := connect.NewResponse(&frontierv1beta1.AuthCallbackResponse{}) @@ -182,9 +167,7 @@ func (h *ConnectHandler) AuthToken(ctx context.Context, request *connect.Request authenticate.ClientCredentialsClientAssertion, authenticate.JWTGrantClientAssertion) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "AuthToken", err, - "grant_type", request.Msg.GetGrantType()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AuthToken: grant_type=%s: %w", request.Msg.GetGrantType(), err)) } if principal.Type == schema.ServiceUserPrincipal { @@ -197,16 +180,13 @@ func (h *ConnectHandler) AuthToken(ctx context.Context, request *connect.Request if errors.Is(err, organization.ErrDisabled) { return nil, connect.NewError(connect.CodeFailedPrecondition, ErrOrgDisabled) } - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AuthToken.orgService.Get: org_id=%s service_user_id=%s: %w", orgId, principal.ServiceUser.ID, err)) } } token, err := h.getAccessToken(ctx, principal, request.Header().Values(consts.ProjectRequestKey), request) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "AuthToken", err, - "principal_id", principal.ID, - "principal_type", principal.Type) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AuthToken: principal_id=%s principal_type=%s: %w", principal.ID, principal.Type, err)) } resp := connect.NewResponse(&frontierv1beta1.AuthTokenResponse{ @@ -270,15 +250,11 @@ func (h *ConnectHandler) getAccessToken(ctx context.Context, principal authentic } func (h *ConnectHandler) AuthLogout(ctx context.Context, request *connect.Request[frontierv1beta1.AuthLogoutRequest]) (*connect.Response[frontierv1beta1.AuthLogoutResponse], error) { - errorLogger := NewErrorLogger() - // delete user session if exists sessionID, err := h.getLoggedInSessionID(ctx) if err == nil { if err = h.sessionService.Delete(ctx, sessionID); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "AuthLogout", err, - "session_id", sessionID.String()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AuthLogout: session_id=%s: %w", sessionID.String(), err)) } } @@ -298,7 +274,6 @@ func (h *ConnectHandler) getLoggedInSessionID(ctx context.Context) (uuid.UUID, e } func (h *ConnectHandler) GetLoggedInPrincipal(ctx context.Context, via ...authenticate.ClientAssertion) (authenticate.Principal, error) { - errorLogger := NewErrorLogger() principal, err := h.authnService.GetPrincipal(ctx, via...) if err != nil { switch { @@ -312,8 +287,7 @@ func (h *ConnectHandler) GetLoggedInPrincipal(ctx context.Context, via ...authen errors.Is(err, patErrors.ErrDisabled): return principal, connect.NewError(connect.CodeUnauthenticated, ErrUnauthenticated) default: - errorLogger.LogUnexpectedError(ctx, nil, "GetLoggedInPrincipal", err) - return principal, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return principal, connect.NewError(connect.CodeInternal, fmt.Errorf("GetLoggedInPrincipal: %w", err)) } } return principal, nil @@ -331,13 +305,10 @@ func (h *ConnectHandler) ListAuthStrategies(ctx context.Context, request *connec } func (h *ConnectHandler) GetJWKs(ctx context.Context, request *connect.Request[frontierv1beta1.GetJWKsRequest]) (*connect.Response[frontierv1beta1.GetJWKsResponse], error) { - errorLogger := NewErrorLogger() - keySet := h.authnService.JWKs(ctx) jwks, err := toJSONWebKey(keySet) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "GetJWKs", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetJWKs: %w", err)) } return connect.NewResponse(&frontierv1beta1.GetJWKsResponse{ Keys: jwks.Keys, diff --git a/internal/api/v1beta1connect/authorize.go b/internal/api/v1beta1connect/authorize.go index 6fb159242..7b16762a1 100644 --- a/internal/api/v1beta1connect/authorize.go +++ b/internal/api/v1beta1connect/authorize.go @@ -93,7 +93,7 @@ func handleAuthErr(err error) error { errors.Is(err, resource.ErrNotExist): return connect.NewError(connect.CodeNotFound, ErrNotFound) default: - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("handleAuthErr: %w", err)) } } @@ -112,19 +112,13 @@ func (h *ConnectHandler) IsSuperUser(ctx context.Context, request connect.AnyReq return connect.NewError(connect.CodePermissionDenied, ErrUnauthorized) case schema.UserPrincipal: if ok, err := h.userService.IsSudo(ctx, currentUser.ID, schema.PlatformSudoPermission); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "IsSuperUser", err, - "user_id", currentUser.ID, - "permission", schema.PlatformSudoPermission) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("IsSuperUser: user_id=%s permission=%s: %w", currentUser.ID, schema.PlatformSudoPermission, err)) } else if ok { return nil } case schema.ServiceUserPrincipal: if ok, err := h.serviceUserService.IsSudo(ctx, currentUser.ID, schema.PlatformSudoPermission); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "IsSuperUser", err, - "service_user_id", currentUser.ID, - "permission", schema.PlatformSudoPermission) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("IsSuperUser: service_user_id=%s permission=%s: %w", currentUser.ID, schema.PlatformSudoPermission, err)) } else if ok { return nil } diff --git a/internal/api/v1beta1connect/billing_check.go b/internal/api/v1beta1connect/billing_check.go index cf5880f2b..20e63ce7c 100644 --- a/internal/api/v1beta1connect/billing_check.go +++ b/internal/api/v1beta1connect/billing_check.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/customer" @@ -10,8 +11,6 @@ import ( ) func (h *ConnectHandler) CheckFeatureEntitlement(ctx context.Context, request *connect.Request[frontierv1beta1.CheckFeatureEntitlementRequest]) (*connect.Response[frontierv1beta1.CheckFeatureEntitlementResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -21,18 +20,12 @@ func (h *ConnectHandler) CheckFeatureEntitlement(ctx context.Context, request *c if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "CheckFeatureEntitlement.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CheckFeatureEntitlement.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } checkStatus, err := h.entitlementService.Check(ctx, cust.ID, request.Msg.GetFeature()) if err != nil { - errorLogger.LogServiceError(ctx, request, "CheckFeatureEntitlement", err, - "billing_id", cust.ID, - "org_id", request.Msg.GetOrgId(), - "feature", request.Msg.GetFeature()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CheckFeatureEntitlement: billing_id=%s org_id=%s feature=%s: %w", cust.ID, request.Msg.GetOrgId(), request.Msg.GetFeature(), err)) } return connect.NewResponse(&frontierv1beta1.CheckFeatureEntitlementResponse{ @@ -41,15 +34,11 @@ func (h *ConnectHandler) CheckFeatureEntitlement(ctx context.Context, request *c } func (h *ConnectHandler) CheckCreditEntitlement(ctx context.Context, request *connect.Request[frontierv1beta1.CheckCreditEntitlementRequest]) (*connect.Response[frontierv1beta1.CheckCreditEntitlementResponse], error) { - errorLogger := NewErrorLogger() - customerList, err := h.customerService.List(ctx, customer.Filter{ OrgID: request.Msg.GetOrgId(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "CheckCreditEntitlement.List", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CheckCreditEntitlement.List: org_id=%s: %w", request.Msg.GetOrgId(), err)) } if len(customerList) == 0 { @@ -59,18 +48,12 @@ func (h *ConnectHandler) CheckCreditEntitlement(ctx context.Context, request *co customer := customerList[0] customerDetails, err := h.customerService.GetDetails(ctx, customer.ID) if err != nil { - errorLogger.LogServiceError(ctx, request, "CheckCreditEntitlement.GetDetails", err, - "customer_id", customer.ID, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CheckCreditEntitlement.GetDetails: customer_id=%s org_id=%s: %w", customer.ID, request.Msg.GetOrgId(), err)) } creditBalance, err := h.creditService.GetBalance(ctx, customer.ID) if err != nil { - errorLogger.LogServiceError(ctx, request, "CheckCreditEntitlement.GetBalance", err, - "customer_id", customer.ID, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CheckCreditEntitlement.GetBalance: customer_id=%s org_id=%s: %w", customer.ID, request.Msg.GetOrgId(), err)) } if creditBalance-request.Msg.GetAmount() >= customerDetails.CreditMin { diff --git a/internal/api/v1beta1connect/billing_check_test.go b/internal/api/v1beta1connect/billing_check_test.go index a04f7cc8e..b9134e15b 100644 --- a/internal/api/v1beta1connect/billing_check_test.go +++ b/internal/api/v1beta1connect/billing_check_test.go @@ -36,7 +36,7 @@ func TestConnectHandler_CheckFeatureEntitlement(t *testing.T) { es.EXPECT().Check(mock.Anything, "billing-123", "feature-abc").Return(false, errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -152,7 +152,7 @@ func TestConnectHandler_CheckCreditEntitlement(t *testing.T) { }).Return(nil, errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -183,7 +183,7 @@ func TestConnectHandler_CheckCreditEntitlement(t *testing.T) { cs.EXPECT().GetDetails(mock.Anything, "customer-123").Return(customer.Details{}, errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -202,7 +202,7 @@ func TestConnectHandler_CheckCreditEntitlement(t *testing.T) { crs.EXPECT().GetBalance(mock.Anything, "customer-123").Return(int64(0), errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { diff --git a/internal/api/v1beta1connect/billing_checkout.go b/internal/api/v1beta1connect/billing_checkout.go index 037e640e0..6dd1f9b56 100644 --- a/internal/api/v1beta1connect/billing_checkout.go +++ b/internal/api/v1beta1connect/billing_checkout.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/checkout" @@ -17,9 +18,7 @@ func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Re // Always infer billing_id from org_id (ignore billing_id from request for security) billingID, err := h.GetBillingAccountFromOrgID(ctx, request.Msg.GetOrgId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateCheckout.GetBillingAccountFromOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateCheckout.GetBillingAccountFromOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } // check if setup requested @@ -30,9 +29,7 @@ func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Re CancelUrl: request.Msg.GetCancelUrl(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateCheckout.CreateSessionForPaymentMethod", err, - "billing_id", billingID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateCheckout.CreateSessionForPaymentMethod: billing_id=%s: %w", billingID, err)) } return connect.NewResponse(&frontierv1beta1.CreateCheckoutResponse{ @@ -53,7 +50,7 @@ func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Re } errorLogger.LogServiceError(ctx, request, "CreateCheckout.CreateSessionForCustomerPortal", err, "billing_id", billingID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateCheckout.CreateSessionForCustomerPortal: billing_id=%s: %w", billingID, err)) } return connect.NewResponse(&frontierv1beta1.CreateCheckoutResponse{ @@ -94,14 +91,7 @@ func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Re if errors.Is(err, product.ErrPerSeatLimitReached) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrPerSeatLimitReached) } - errorLogger.LogServiceError(ctx, request, "CreateCheckout.Create", err, - "billing_id", billingID, - "plan_id", planID, - "product_id", featureID, - "quantity", quantity, - "skip_trial", skipTrial, - "cancel_after_trial", cancelAfterTrial) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateCheckout.Create: billing_id=%s plan_id=%s product_id=%s quantity=%d skip_trial=%v cancel_after_trial=%v: %w", billingID, planID, featureID, quantity, skipTrial, cancelAfterTrial, err)) } return connect.NewResponse(&frontierv1beta1.CreateCheckoutResponse{ @@ -110,14 +100,10 @@ func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Re } func (h *ConnectHandler) DelegatedCheckout(ctx context.Context, request *connect.Request[frontierv1beta1.DelegatedCheckoutRequest]) (*connect.Response[frontierv1beta1.DelegatedCheckoutResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id (ignore billing_id from request for security) billingID, err := h.GetBillingAccountFromOrgID(ctx, request.Msg.GetOrgId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "DelegatedCheckout.GetBillingAccountFromOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DelegatedCheckout.GetBillingAccountFromOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } var planID string @@ -146,29 +132,19 @@ func (h *ConnectHandler) DelegatedCheckout(ctx context.Context, request *connect ProviderCouponID: providerCouponID, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "DelegatedCheckout.Apply", err, - "billing_id", billingID, - "plan_id", planID, - "product_id", productID, - "product_quantity", productQuantity, - "skip_trial", skipTrial, - "cancel_after_trial", cancelAfterTrail, - "provider_coupon_id", providerCouponID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DelegatedCheckout.Apply: billing_id=%s plan_id=%s product_id=%s product_quantity=%d skip_trial=%v cancel_after_trial=%v provider_coupon_id=%s: %w", billingID, planID, productID, productQuantity, skipTrial, cancelAfterTrail, providerCouponID, err)) } var subsPb *frontierv1beta1.Subscription if subs != nil { if subsPb, err = transformSubscriptionToPB(*subs); err != nil { - errorLogger.LogTransformError(ctx, request, "DelegatedCheckout", subs.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DelegatedCheckout: subscription_id=%s: %w", subs.ID, err)) } } var productPb *frontierv1beta1.Product if prod != nil { if productPb, err = transformProductToPB(*prod); err != nil { - errorLogger.LogTransformError(ctx, request, "DelegatedCheckout", prod.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DelegatedCheckout: product_id=%s: %w", prod.ID, err)) } } @@ -179,8 +155,6 @@ func (h *ConnectHandler) DelegatedCheckout(ctx context.Context, request *connect } func (h *ConnectHandler) ListCheckouts(ctx context.Context, request *connect.Request[frontierv1beta1.ListCheckoutsRequest]) (*connect.Response[frontierv1beta1.ListCheckoutsResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetOrgId() == "" { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -188,9 +162,7 @@ func (h *ConnectHandler) ListCheckouts(ctx context.Context, request *connect.Req // Always infer billing_id from org_id (ignore billing_id from request for security) billingID, err := h.GetBillingAccountFromOrgID(ctx, request.Msg.GetOrgId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListCheckouts.GetBillingAccountFromOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCheckouts.GetBillingAccountFromOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } var checkouts []*frontierv1beta1.CheckoutSession @@ -198,10 +170,7 @@ func (h *ConnectHandler) ListCheckouts(ctx context.Context, request *connect.Req CustomerID: billingID, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListCheckouts.List", err, - "billing_id", billingID, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCheckouts.List: billing_id=%s org_id=%s: %w", billingID, request.Msg.GetOrgId(), err)) } for _, v := range checkoutList { checkouts = append(checkouts, transformCheckoutToPB(v)) @@ -213,17 +182,13 @@ func (h *ConnectHandler) ListCheckouts(ctx context.Context, request *connect.Req } func (h *ConnectHandler) GetCheckout(ctx context.Context, request *connect.Request[frontierv1beta1.GetCheckoutRequest]) (*connect.Response[frontierv1beta1.GetCheckoutResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetId() == "" { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } ch, err := h.checkoutService.GetByID(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetCheckout.GetByID", err, - "checkout_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCheckout.GetByID: checkout_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.GetCheckoutResponse{ diff --git a/internal/api/v1beta1connect/billing_checkout_test.go b/internal/api/v1beta1connect/billing_checkout_test.go index e7ad377d5..ce8f8c19c 100644 --- a/internal/api/v1beta1connect/billing_checkout_test.go +++ b/internal/api/v1beta1connect/billing_checkout_test.go @@ -269,7 +269,7 @@ func TestConnectHandler_CreateCheckout(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("service error"), }, { name: "should return internal server error when customer portal setup fails", @@ -288,7 +288,7 @@ func TestConnectHandler_CreateCheckout(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("service error"), }, { name: "should return internal server error when subscription checkout fails", @@ -308,7 +308,7 @@ func TestConnectHandler_CreateCheckout(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("service error"), }, { name: "should return internal server error when product checkout fails", @@ -328,7 +328,7 @@ func TestConnectHandler_CreateCheckout(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("service error"), }, } @@ -456,7 +456,7 @@ func TestConnectHandler_DelegatedCheckout(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("service error"), }, } @@ -525,7 +525,7 @@ func TestConnectHandler_ListCheckouts(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("ListCheckouts.List: billing_id=test-billing-id org_id=test-org-id: service error"), }, { name: "should return empty list if no checkouts found", @@ -690,7 +690,7 @@ func TestConnectHandler_GetCheckout(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("GetCheckout.GetByID: checkout_id=test-checkout-id: service error"), }, { name: "should return checkout successfully", diff --git a/internal/api/v1beta1connect/billing_customer.go b/internal/api/v1beta1connect/billing_customer.go index 161b2ddc1..0aa56e58f 100644 --- a/internal/api/v1beta1connect/billing_customer.go +++ b/internal/api/v1beta1connect/billing_customer.go @@ -14,8 +14,6 @@ import ( ) func (h *ConnectHandler) CreateBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.CreateBillingAccountRequest]) (*connect.Response[frontierv1beta1.CreateBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - var stripeTestClockID *string if val, ok := customer.GetStripeTestClockFromContext(ctx); ok { stripeTestClockID = &val @@ -57,19 +55,12 @@ func (h *ConnectHandler) CreateBillingAccount(ctx context.Context, request *conn if errors.Is(err, customer.ErrActiveConflict) { return nil, connect.NewError(connect.CodeFailedPrecondition, err) } - errorLogger.LogServiceError(ctx, request, "CreateBillingAccount.Create", err, - "org_id", request.Msg.GetOrgId(), - "customer_name", request.Msg.GetBody().GetName(), - "customer_email", request.Msg.GetBody().GetEmail(), - "currency", request.Msg.GetBody().GetCurrency(), - "offline", request.Msg.GetOffline()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateBillingAccount.Create: org_id=%s customer_name=%s customer_email=%s currency=%s offline=%v: %w", request.Msg.GetOrgId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetEmail(), request.Msg.GetBody().GetCurrency(), request.Msg.GetOffline(), err)) } customerPB, err := transformCustomerToPB(newCustomer) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateBillingAccount", newCustomer.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateBillingAccount: customer_id=%s: %w", newCustomer.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreateBillingAccountResponse{ BillingAccount: customerPB, @@ -77,8 +68,6 @@ func (h *ConnectHandler) CreateBillingAccount(ctx context.Context, request *conn } func (h *ConnectHandler) UpdateBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.UpdateBillingAccountRequest]) (*connect.Response[frontierv1beta1.UpdateBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - var metaDataMap metadata.Metadata if request.Msg.GetBody().GetMetadata() != nil { metaDataMap = metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) @@ -116,18 +105,12 @@ func (h *ConnectHandler) UpdateBillingAccount(ctx context.Context, request *conn TaxData: customerTaxes, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "UpdateBillingAccount.Update", err, - "customer_id", request.Msg.GetId(), - "customer_name", request.Msg.GetBody().GetName(), - "customer_email", request.Msg.GetBody().GetEmail(), - "currency", request.Msg.GetBody().GetCurrency()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateBillingAccount.Update: customer_id=%s customer_name=%s customer_email=%s currency=%s: %w", request.Msg.GetId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetEmail(), request.Msg.GetBody().GetCurrency(), err)) } customerPB, err := transformCustomerToPB(updatedCustomer) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateBillingAccount", updatedCustomer.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateBillingAccount: customer_id=%s: %w", updatedCustomer.ID, err)) } return connect.NewResponse(&frontierv1beta1.UpdateBillingAccountResponse{ @@ -145,14 +128,12 @@ func (h *ConnectHandler) RegisterBillingAccount(ctx context.Context, request *co } errorLogger.LogServiceError(ctx, request, "RegisterBillingAccount.RegisterToProviderIfRequired", err, "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RegisterBillingAccount.RegisterToProviderIfRequired: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.RegisterBillingAccountResponse{}), nil } func (h *ConnectHandler) ListBillingAccounts(ctx context.Context, request *connect.Request[frontierv1beta1.ListBillingAccountsRequest]) (*connect.Response[frontierv1beta1.ListBillingAccountsResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetOrgId() == "" { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -161,15 +142,12 @@ func (h *ConnectHandler) ListBillingAccounts(ctx context.Context, request *conne OrgID: request.Msg.GetOrgId(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListBillingAccounts.List", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListBillingAccounts.List: org_id=%s: %w", request.Msg.GetOrgId(), err)) } for _, v := range customerList { customerPB, err := transformCustomerToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListBillingAccounts", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListBillingAccounts: customer_id=%s: %w", v.ID, err)) } customers = append(customers, customerPB) } @@ -185,49 +163,33 @@ func (h *ConnectHandler) ListBillingAccounts(ctx context.Context, request *conne } func (h *ConnectHandler) DeleteBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteBillingAccountRequest]) (*connect.Response[frontierv1beta1.DeleteBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - err := h.customerService.Delete(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteBillingAccount.Delete", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteBillingAccount.Delete: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.DeleteBillingAccountResponse{}), nil } func (h *ConnectHandler) EnableBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.EnableBillingAccountRequest]) (*connect.Response[frontierv1beta1.EnableBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - err := h.customerService.Enable(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "EnableBillingAccount.Enable", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableBillingAccount.Enable: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.EnableBillingAccountResponse{}), nil } func (h *ConnectHandler) DisableBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.DisableBillingAccountRequest]) (*connect.Response[frontierv1beta1.DisableBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - err := h.customerService.Disable(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "DisableBillingAccount.Disable", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DisableBillingAccount.Disable: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.DisableBillingAccountResponse{}), nil } func (h *ConnectHandler) GetBillingBalance(ctx context.Context, request *connect.Request[frontierv1beta1.GetBillingBalanceRequest]) (*connect.Response[frontierv1beta1.GetBillingBalanceResponse], error) { - errorLogger := NewErrorLogger() - balanceAmount, err := h.creditService.GetBalance(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetBillingBalance.GetBalance", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingBalance.GetBalance: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.GetBillingBalanceResponse{ Balance: &frontierv1beta1.BillingAccount_Balance{ @@ -238,14 +200,9 @@ func (h *ConnectHandler) GetBillingBalance(ctx context.Context, request *connect } func (h *ConnectHandler) HasTrialed(ctx context.Context, request *connect.Request[frontierv1beta1.HasTrialedRequest]) (*connect.Response[frontierv1beta1.HasTrialedResponse], error) { - errorLogger := NewErrorLogger() - hasTrialed, err := h.subscriptionService.HasUserSubscribedBefore(ctx, request.Msg.GetId(), request.Msg.GetPlanId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "HasTrialed.HasUserSubscribedBefore", err, - "customer_id", request.Msg.GetId(), - "plan_id", request.Msg.GetPlanId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("HasTrialed.HasUserSubscribedBefore: customer_id=%s plan_id=%s: %w", request.Msg.GetId(), request.Msg.GetPlanId(), err)) } return connect.NewResponse(&frontierv1beta1.HasTrialedResponse{ Trialed: hasTrialed, @@ -253,22 +210,17 @@ func (h *ConnectHandler) HasTrialed(ctx context.Context, request *connect.Reques } func (h *ConnectHandler) ListAllBillingAccounts(ctx context.Context, request *connect.Request[frontierv1beta1.ListAllBillingAccountsRequest]) (*connect.Response[frontierv1beta1.ListAllBillingAccountsResponse], error) { - errorLogger := NewErrorLogger() - var customers []*frontierv1beta1.BillingAccount customerList, err := h.customerService.List(ctx, customer.Filter{ OrgID: request.Msg.GetOrgId(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListAllBillingAccounts.List", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllBillingAccounts.List: org_id=%s: %w", request.Msg.GetOrgId(), err)) } for _, v := range customerList { customerPB, err := transformCustomerToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListAllBillingAccounts", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllBillingAccounts: customer_id=%s: %w", v.ID, err)) } customers = append(customers, customerPB) } @@ -315,27 +267,18 @@ func transformCustomerToPB(customer customer.Customer) (*frontierv1beta1.Billing } func (h *ConnectHandler) UpdateBillingAccountLimits(ctx context.Context, request *connect.Request[frontierv1beta1.UpdateBillingAccountLimitsRequest]) (*connect.Response[frontierv1beta1.UpdateBillingAccountLimitsResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.customerService.UpdateCreditMinByID(ctx, request.Msg.GetId(), request.Msg.GetCreditMin()) if err != nil { - errorLogger.LogServiceError(ctx, request, "UpdateBillingAccountLimits.UpdateCreditMinByID", err, - "customer_id", request.Msg.GetId(), - "credit_min", request.Msg.GetCreditMin()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateBillingAccountLimits.UpdateCreditMinByID: customer_id=%s credit_min=%d: %w", request.Msg.GetId(), request.Msg.GetCreditMin(), err)) } return connect.NewResponse(&frontierv1beta1.UpdateBillingAccountLimitsResponse{}), nil } func (h *ConnectHandler) GetBillingAccountDetails(ctx context.Context, request *connect.Request[frontierv1beta1.GetBillingAccountDetailsRequest]) (*connect.Response[frontierv1beta1.GetBillingAccountDetailsResponse], error) { - errorLogger := NewErrorLogger() - details, err := h.customerService.GetDetails(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetBillingAccountDetails.GetDetails", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccountDetails.GetDetails: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.GetBillingAccountDetailsResponse{ @@ -354,22 +297,19 @@ func (h *ConnectHandler) GetBillingAccount(ctx context.Context, request *connect } errorLogger.LogServiceError(ctx, request, "GetBillingAccount.GetByID", err, "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccount.GetByID: customer_id=%s: %w", request.Msg.GetId(), err)) } var paymentMethodsPbs []*frontierv1beta1.PaymentMethod if request.Msg.GetWithPaymentMethods() { pms, err := h.customerService.ListPaymentMethods(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetBillingAccount.ListPaymentMethods", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccount.ListPaymentMethods: customer_id=%s: %w", request.Msg.GetId(), err)) } for _, v := range pms { pmPB, err := transformPaymentMethodToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetBillingAccount", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccount: payment_method_id=%s: %w", v.ID, err)) } paymentMethodsPbs = append(paymentMethodsPbs, pmPB) } @@ -379,9 +319,7 @@ func (h *ConnectHandler) GetBillingAccount(ctx context.Context, request *connect if request.Msg.GetWithBillingDetails() { billingDetails, err := h.customerService.GetDetails(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetBillingAccount.GetDetails", err, - "customer_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccount.GetDetails: customer_id=%s: %w", request.Msg.GetId(), err)) } billingDetailsPb = &frontierv1beta1.BillingAccountDetails{ CreditMin: billingDetails.CreditMin, @@ -391,8 +329,7 @@ func (h *ConnectHandler) GetBillingAccount(ctx context.Context, request *connect customerPB, err := transformCustomerToPB(customerOb) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetBillingAccount", customerOb.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccount: customer_id=%s: %w", customerOb.ID, err)) } response := &frontierv1beta1.GetBillingAccountResponse{ @@ -438,11 +375,7 @@ func (h *ConnectHandler) UpdateBillingAccountDetails(ctx context.Context, reques DueInDays: request.Msg.GetDueInDays(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "UpdateBillingAccountDetails.UpdateDetails", err, - "customer_id", request.Msg.GetId(), - "credit_min", request.Msg.GetCreditMin(), - "due_in_days", request.Msg.GetDueInDays()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateBillingAccountDetails.UpdateDetails: customer_id=%s credit_min=%d due_in_days=%d: %w", request.Msg.GetId(), request.Msg.GetCreditMin(), request.Msg.GetDueInDays(), err)) } // Add audit log - infer org_id from billing account diff --git a/internal/api/v1beta1connect/billing_customer_test.go b/internal/api/v1beta1connect/billing_customer_test.go index 1a0ca89e6..07e776749 100644 --- a/internal/api/v1beta1connect/billing_customer_test.go +++ b/internal/api/v1beta1connect/billing_customer_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "connectrpc.com/connect" @@ -56,7 +57,7 @@ func TestHandler_UpdateBillingAccountDetails(t *testing.T) { }), mockUpdateError: errors.New("failed to update details"), expectError: true, - expectedError: connect.NewError(connect.CodeInternal, ErrInternalServerError), + expectedError: connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateBillingAccountDetails.UpdateDetails: customer_id=billing-account-id credit_min=-100 due_in_days=30: %w", errors.New("failed to update details"))), }, } diff --git a/internal/api/v1beta1connect/billing_invoice.go b/internal/api/v1beta1connect/billing_invoice.go index 0e468f902..d43c98685 100644 --- a/internal/api/v1beta1connect/billing_invoice.go +++ b/internal/api/v1beta1connect/billing_invoice.go @@ -16,25 +16,19 @@ import ( ) func (h *ConnectHandler) ListAllInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.ListAllInvoicesRequest]) (*connect.Response[frontierv1beta1.ListAllInvoicesResponse], error) { - errorLogger := NewErrorLogger() - paginate := pagination.NewPagination(request.Msg.GetPageNum(), request.Msg.GetPageSize()) invoices, err := h.invoiceService.ListAll(ctx, invoice.Filter{ Pagination: paginate, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListAllInvoices.ListAll", err, - "page_num", request.Msg.GetPageNum(), - "page_size", request.Msg.GetPageSize()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllInvoices.ListAll: page_num=%d page_size=%d: %w", request.Msg.GetPageNum(), request.Msg.GetPageSize(), err)) } var invoicePBs []*frontierv1beta1.Invoice for _, v := range invoices { invoicePB, err := transformInvoiceToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListAllInvoices", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllInvoices: invoice_id=%s: %w", v.ID, err)) } invoicePBs = append(invoicePBs, invoicePB) } @@ -63,7 +57,7 @@ func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Requ } errorLogger.LogServiceError(ctx, request, "ListInvoices.GetByOrgID", err, "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListInvoices.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID @@ -72,18 +66,13 @@ func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Requ NonZeroOnly: request.Msg.GetNonzeroAmountOnly(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListInvoices.List", err, - "org_id", request.Msg.GetOrgId(), - "billing_id", billingID, - "nonzero_amount_only", request.Msg.GetNonzeroAmountOnly()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListInvoices.List: org_id=%s billing_id=%s nonzero_amount_only=%v: %w", request.Msg.GetOrgId(), billingID, request.Msg.GetNonzeroAmountOnly(), err)) } var invoicePBs []*frontierv1beta1.Invoice for _, v := range invoices { invoicePB, err := transformInvoiceToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListInvoices", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListInvoices: invoice_id=%s: %w", v.ID, err)) } invoicePBs = append(invoicePBs, invoicePB) } @@ -116,21 +105,17 @@ func (h *ConnectHandler) GetUpcomingInvoice(ctx context.Context, request *connec } errorLogger.LogServiceError(ctx, request, "GetUpcomingInvoice.GetByOrgID", err, "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetUpcomingInvoice.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID invoice, err := h.invoiceService.GetUpcoming(ctx, billingID) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetUpcomingInvoice.GetUpcoming", err, - "org_id", request.Msg.GetOrgId(), - "billing_id", billingID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetUpcomingInvoice.GetUpcoming: org_id=%s billing_id=%s: %w", request.Msg.GetOrgId(), billingID, err)) } invoicePB, err := transformInvoiceToPB(invoice) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetUpcomingInvoice", invoice.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetUpcomingInvoice: invoice_id=%s: %w", invoice.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetUpcomingInvoiceResponse{ @@ -173,12 +158,9 @@ func transformInvoiceToPB(i invoice.Invoice) (*frontierv1beta1.Invoice, error) { } func (h *ConnectHandler) GenerateInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.GenerateInvoicesRequest]) (*connect.Response[frontierv1beta1.GenerateInvoicesResponse], error) { - errorLogger := NewErrorLogger() - err := h.invoiceService.TriggerCreditOverdraftInvoices(ctx) if err != nil { - errorLogger.LogServiceError(ctx, request, "GenerateInvoices.TriggerCreditOverdraftInvoices", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GenerateInvoices.TriggerCreditOverdraftInvoices: %w", err)) } return connect.NewResponse(&frontierv1beta1.GenerateInvoicesResponse{}), nil } @@ -206,7 +188,7 @@ func (h *ConnectHandler) SearchInvoices(ctx context.Context, request *connect.Re errorLogger.LogServiceError(ctx, request, "SearchInvoices.SearchInvoices", err, "query_offset", rqlQuery.Offset, "query_limit", rqlQuery.Limit) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchInvoices.SearchInvoices: query_offset=%d query_limit=%d: %w", rqlQuery.Offset, rqlQuery.Limit, err)) } for _, v := range invoicesData { diff --git a/internal/api/v1beta1connect/billing_invoice_test.go b/internal/api/v1beta1connect/billing_invoice_test.go index e212cee1e..0f5261102 100644 --- a/internal/api/v1beta1connect/billing_invoice_test.go +++ b/internal/api/v1beta1connect/billing_invoice_test.go @@ -47,7 +47,7 @@ func TestConnectHandler_ListInvoices(t *testing.T) { NonzeroAmountOnly: false, }), want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -274,7 +274,7 @@ func TestConnectHandler_ListInvoices(t *testing.T) { NonzeroAmountOnly: false, }), want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } @@ -335,7 +335,7 @@ func TestConnectHandler_GetUpcomingInvoice(t *testing.T) { OrgId: "org-123", }), want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -490,7 +490,7 @@ func TestConnectHandler_GetUpcomingInvoice(t *testing.T) { OrgId: "org-123", }), want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } diff --git a/internal/api/v1beta1connect/billing_plan.go b/internal/api/v1beta1connect/billing_plan.go index b7f12e201..d2a5cf0e9 100644 --- a/internal/api/v1beta1connect/billing_plan.go +++ b/internal/api/v1beta1connect/billing_plan.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/plan" @@ -13,8 +14,6 @@ import ( ) func (h *ConnectHandler) CreatePlan(ctx context.Context, request *connect.Request[frontierv1beta1.CreatePlanRequest]) (*connect.Response[frontierv1beta1.CreatePlanResponse], error) { - errorLogger := NewErrorLogger() - metaDataMap := metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) // parse products var products []product.Product @@ -80,44 +79,32 @@ func (h *ConnectHandler) CreatePlan(ctx context.Context, request *connect.Reques Products: products, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreatePlan.UpsertPlans", err, - "plan_name", planToCreate.Name, - "plan_title", planToCreate.Title, - "interval", planToCreate.Interval, - "product_count", len(products)) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePlan.UpsertPlans: plan_name=%s plan_title=%s interval=%s product_count=%d: %w", planToCreate.Name, planToCreate.Title, planToCreate.Interval, len(products), err)) } newPlan, err := h.planService.GetByID(ctx, planToCreate.Name) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreatePlan.GetByID", err, - "plan_name", planToCreate.Name) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePlan.GetByID: plan_name=%s: %w", planToCreate.Name, err)) } planPB, err := transformPlanToPB(newPlan) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreatePlan", newPlan.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePlan: plan_id=%s: %w", newPlan.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreatePlanResponse{Plan: planPB}), nil } func (h *ConnectHandler) ListPlans(ctx context.Context, request *connect.Request[frontierv1beta1.ListPlansRequest]) (*connect.Response[frontierv1beta1.ListPlansResponse], error) { - errorLogger := NewErrorLogger() - var plans []*frontierv1beta1.Plan planList, err := h.planService.List(ctx, plan.Filter{}) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListPlans.List", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlans.List: %w", err)) } for _, v := range planList { planPB, err := transformPlanToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListPlans", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlans: plan_id=%s: %w", v.ID, err)) } plans = append(plans, planPB) } @@ -126,19 +113,14 @@ func (h *ConnectHandler) ListPlans(ctx context.Context, request *connect.Request } func (h *ConnectHandler) GetPlan(ctx context.Context, request *connect.Request[frontierv1beta1.GetPlanRequest]) (*connect.Response[frontierv1beta1.GetPlanResponse], error) { - errorLogger := NewErrorLogger() - planOb, err := h.planService.GetByID(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetPlan.GetByID", err, - "plan_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetPlan.GetByID: plan_id=%s: %w", request.Msg.GetId(), err)) } planPB, err := transformPlanToPB(planOb) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetPlan", planOb.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetPlan: plan_id=%s: %w", planOb.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetPlanResponse{Plan: planPB}), nil diff --git a/internal/api/v1beta1connect/billing_plan_test.go b/internal/api/v1beta1connect/billing_plan_test.go index 8a751f5ad..2cb59654e 100644 --- a/internal/api/v1beta1connect/billing_plan_test.go +++ b/internal/api/v1beta1connect/billing_plan_test.go @@ -49,7 +49,7 @@ func TestConnectHandler_CreatePlan(t *testing.T) { setup: func(ps *mocks.PlanService) { ps.On("UpsertPlans", mock.Anything, mock.Anything).Return(errors.New("upsert failed")) }, - wantErr: ErrInternalServerError, + wantErr: errors.New("upsert failed"), errCode: connect.CodeInternal, }, { @@ -68,7 +68,7 @@ func TestConnectHandler_CreatePlan(t *testing.T) { ps.On("UpsertPlans", mock.Anything, mock.Anything).Return(nil) ps.On("GetByID", mock.Anything, "basic-plan").Return(plan.Plan{}, errors.New("get failed")) }, - wantErr: ErrInternalServerError, + wantErr: errors.New("get failed"), errCode: connect.CodeInternal, }, { @@ -378,7 +378,7 @@ func TestConnectHandler_ListPlans(t *testing.T) { setup: func(ps *mocks.PlanService) { ps.On("List", mock.Anything, plan.Filter{}).Return([]plan.Plan{}, errors.New("service failed")) }, - wantErr: ErrInternalServerError, + wantErr: errors.New("service failed"), errCode: connect.CodeInternal, }, { @@ -462,7 +462,7 @@ func TestConnectHandler_ListPlans(t *testing.T) { }, }, nil) }, - wantErr: ErrInternalServerError, + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } @@ -515,7 +515,7 @@ func TestConnectHandler_GetPlan(t *testing.T) { setup: func(ps *mocks.PlanService) { ps.On("GetByID", mock.Anything, "plan-123").Return(plan.Plan{}, errors.New("service failed")) }, - wantErr: ErrInternalServerError, + wantErr: errors.New("service failed"), errCode: connect.CodeInternal, }, { @@ -563,7 +563,7 @@ func TestConnectHandler_GetPlan(t *testing.T) { Metadata: metadata.Metadata{"invalid": make(chan int)}, // This will cause ToStructPB to fail }, nil) }, - wantErr: ErrInternalServerError, + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } diff --git a/internal/api/v1beta1connect/billing_product.go b/internal/api/v1beta1connect/billing_product.go index 617468ae3..d18879b98 100644 --- a/internal/api/v1beta1connect/billing_product.go +++ b/internal/api/v1beta1connect/billing_product.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/product" @@ -11,19 +12,15 @@ import ( ) func (h *ConnectHandler) ListProducts(ctx context.Context, request *connect.Request[frontierv1beta1.ListProductsRequest]) (*connect.Response[frontierv1beta1.ListProductsResponse], error) { - errorLogger := NewErrorLogger() - var products []*frontierv1beta1.Product productsList, err := h.productService.List(ctx, product.Filter{}) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProducts.List", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProducts.List: %w", err)) } for _, v := range productsList { productPB, err := transformProductToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProducts", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProducts: entity_id=%s: %w", v.ID, err)) } products = append(products, productPB) } @@ -34,19 +31,14 @@ func (h *ConnectHandler) ListProducts(ctx context.Context, request *connect.Requ } func (h *ConnectHandler) GetProduct(ctx context.Context, request *connect.Request[frontierv1beta1.GetProductRequest]) (*connect.Response[frontierv1beta1.GetProductResponse], error) { - errorLogger := NewErrorLogger() - product, err := h.productService.GetByID(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetProduct.GetByID", err, - "product_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProduct.GetByID: product_id=%s: %w", request.Msg.GetId(), err)) } productPB, err := transformProductToPB(product) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetProduct", product.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProduct: entity_id=%s: %w", product.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetProductResponse{ @@ -55,8 +47,6 @@ func (h *ConnectHandler) GetProduct(ctx context.Context, request *connect.Reques } func (h *ConnectHandler) CreateProduct(ctx context.Context, request *connect.Request[frontierv1beta1.CreateProductRequest]) (*connect.Response[frontierv1beta1.CreateProductResponse], error) { - errorLogger := NewErrorLogger() - metaDataMap := metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) // parse price var productPrices []product.Price @@ -104,20 +94,14 @@ func (h *ConnectHandler) CreateProduct(ctx context.Context, request *connect.Req Metadata: metaDataMap, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateProduct.Create", err, - "product_name", request.Msg.GetBody().GetName(), - "product_title", request.Msg.GetBody().GetTitle(), - "plan_id", request.Msg.GetBody().GetPlanId(), - "behavior", request.Msg.GetBody().GetBehavior(), - "price_count", len(productPrices), - "feature_count", len(productFeatures)) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProduct.Create: product_name=%s product_title=%s plan_id=%s behavior=%s price_count=%d feature_count=%d: %w", + request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetPlanId(), + request.Msg.GetBody().GetBehavior(), len(productPrices), len(productFeatures), err)) } productPB, err := transformProductToPB(newProduct) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateProduct", newProduct.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProduct: entity_id=%s: %w", newProduct.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreateProductResponse{ @@ -126,8 +110,6 @@ func (h *ConnectHandler) CreateProduct(ctx context.Context, request *connect.Req } func (h *ConnectHandler) UpdateProduct(ctx context.Context, request *connect.Request[frontierv1beta1.UpdateProductRequest]) (*connect.Response[frontierv1beta1.UpdateProductResponse], error) { - errorLogger := NewErrorLogger() - metaDataMap := metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) // parse price var productPrices []product.Price @@ -170,19 +152,13 @@ func (h *ConnectHandler) UpdateProduct(ctx context.Context, request *connect.Req Metadata: metaDataMap, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "UpdateProduct.Update", err, - "product_id", request.Msg.GetId(), - "product_name", request.Msg.GetBody().GetName(), - "product_title", request.Msg.GetBody().GetTitle(), - "behavior", request.Msg.GetBody().GetBehavior(), - "price_count", len(productPrices), - "feature_count", len(productFeatures)) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProduct.Update: product_id=%s product_name=%s product_title=%s behavior=%s price_count=%d feature_count=%d: %w", + request.Msg.GetId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), + request.Msg.GetBody().GetBehavior(), len(productPrices), len(productFeatures), err)) } productPb, err := transformProductToPB(updatedProduct) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateProduct", updatedProduct.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProduct: entity_id=%s: %w", updatedProduct.ID, err)) } return connect.NewResponse(&frontierv1beta1.UpdateProductResponse{ @@ -191,20 +167,16 @@ func (h *ConnectHandler) UpdateProduct(ctx context.Context, request *connect.Req } func (h *ConnectHandler) ListFeatures(ctx context.Context, request *connect.Request[frontierv1beta1.ListFeaturesRequest]) (*connect.Response[frontierv1beta1.ListFeaturesResponse], error) { - errorLogger := NewErrorLogger() - features, err := h.productService.ListFeatures(ctx, product.Filter{}) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListFeatures.ListFeatures", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListFeatures.ListFeatures: %w", err)) } var featuresPB []*frontierv1beta1.Feature for _, v := range features { f, err := transformFeatureToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListFeatures", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListFeatures: entity_id=%s: %w", v.ID, err)) } featuresPB = append(featuresPB, f) } @@ -215,8 +187,6 @@ func (h *ConnectHandler) ListFeatures(ctx context.Context, request *connect.Requ } func (h *ConnectHandler) CreateFeature(ctx context.Context, request *connect.Request[frontierv1beta1.CreateFeatureRequest]) (*connect.Response[frontierv1beta1.CreateFeatureResponse], error) { - errorLogger := NewErrorLogger() - metaDataMap := metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) newFeature, err := h.productService.UpsertFeature(ctx, product.Feature{ Name: request.Msg.GetBody().GetName(), @@ -228,17 +198,13 @@ func (h *ConnectHandler) CreateFeature(ctx context.Context, request *connect.Req if errors.Is(err, product.ErrInvalidFeatureDetail) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "CreateFeature.UpsertFeature", err, - "feature_name", request.Msg.GetBody().GetName(), - "feature_title", request.Msg.GetBody().GetTitle(), - "product_ids", request.Msg.GetBody().GetProductIds()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateFeature.UpsertFeature: feature_name=%s feature_title=%s product_ids=%v: %w", + request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetProductIds(), err)) } featurePB, err := transformFeatureToPB(newFeature) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateFeature", newFeature.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateFeature: entity_id=%s: %w", newFeature.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreateFeatureResponse{ @@ -247,8 +213,6 @@ func (h *ConnectHandler) CreateFeature(ctx context.Context, request *connect.Req } func (h *ConnectHandler) UpdateFeature(ctx context.Context, request *connect.Request[frontierv1beta1.UpdateFeatureRequest]) (*connect.Response[frontierv1beta1.UpdateFeatureResponse], error) { - errorLogger := NewErrorLogger() - metaDataMap := metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) updatedFeature, err := h.productService.UpsertFeature(ctx, product.Feature{ ID: request.Msg.GetId(), @@ -261,18 +225,13 @@ func (h *ConnectHandler) UpdateFeature(ctx context.Context, request *connect.Req if errors.Is(err, product.ErrInvalidFeatureDetail) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "UpdateFeature.UpsertFeature", err, - "feature_id", request.Msg.GetId(), - "feature_name", request.Msg.GetBody().GetName(), - "feature_title", request.Msg.GetBody().GetTitle(), - "product_ids", request.Msg.GetBody().GetProductIds()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateFeature.UpsertFeature: feature_id=%s feature_name=%s feature_title=%s product_ids=%v: %w", + request.Msg.GetId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetProductIds(), err)) } featurePB, err := transformFeatureToPB(updatedFeature) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateFeature", updatedFeature.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateFeature: entity_id=%s: %w", updatedFeature.ID, err)) } return connect.NewResponse(&frontierv1beta1.UpdateFeatureResponse{ @@ -281,19 +240,14 @@ func (h *ConnectHandler) UpdateFeature(ctx context.Context, request *connect.Req } func (h *ConnectHandler) GetFeature(ctx context.Context, request *connect.Request[frontierv1beta1.GetFeatureRequest]) (*connect.Response[frontierv1beta1.GetFeatureResponse], error) { - errorLogger := NewErrorLogger() - feature, err := h.productService.GetFeatureByID(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetFeature.GetFeatureByID", err, - "feature_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetFeature.GetFeatureByID: feature_id=%s: %w", request.Msg.GetId(), err)) } featurePB, err := transformFeatureToPB(feature) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetFeature", feature.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetFeature: entity_id=%s: %w", feature.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetFeatureResponse{ diff --git a/internal/api/v1beta1connect/billing_product_test.go b/internal/api/v1beta1connect/billing_product_test.go index 471cb29ea..57b8ad1a4 100644 --- a/internal/api/v1beta1connect/billing_product_test.go +++ b/internal/api/v1beta1connect/billing_product_test.go @@ -35,7 +35,7 @@ func TestConnectHandler_ListProducts(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("ListProducts.List: service error"), }, { name: "should return empty list if no products found", @@ -261,7 +261,7 @@ func TestConnectHandler_GetProduct(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("GetProduct.GetByID: product_id=product-1: service error"), }, { name: "should return product successfully with minimal data", @@ -431,7 +431,7 @@ func TestConnectHandler_GetProduct(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("GetProduct.GetByID: product_id=: not found"), }, } @@ -524,7 +524,7 @@ func TestConnectHandler_CreateProduct(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("CreateProduct.Create: product_name=Test Product product_title=Test Product Title plan_id=plan-1 behavior=basic price_count=0 feature_count=0: service error"), }, { name: "should create product successfully with minimal data", @@ -605,7 +605,7 @@ func TestConnectHandler_CreateProduct(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("CreateProduct.Create: product_name= product_title= plan_id= behavior= price_count=0 feature_count=0: validation error"), }, } @@ -677,7 +677,7 @@ func TestConnectHandler_UpdateProduct(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("UpdateProduct.Update: product_id=product-1 product_name=Updated Product product_title=Updated Product Title behavior=basic price_count=0 feature_count=0: service error"), }, { name: "should update product successfully with minimal data", @@ -878,7 +878,7 @@ func TestConnectHandler_UpdateProduct(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("UpdateProduct.Update: product_id= product_name= product_title= behavior= price_count=0 feature_count=0: not found"), }, } @@ -942,7 +942,7 @@ func TestConnectHandler_ListFeatures(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("ListFeatures.ListFeatures: service error"), }, { name: "should return empty list when no features exist", @@ -1063,7 +1063,7 @@ func TestConnectHandler_GetFeature(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("GetFeature.GetFeatureByID: feature_id=feature-1: service error"), }, { name: "should return feature successfully with minimal data", @@ -1138,7 +1138,7 @@ func TestConnectHandler_GetFeature(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: errors.New("GetFeature.GetFeatureByID: feature_id=: not found"), }, } diff --git a/internal/api/v1beta1connect/billing_subscription.go b/internal/api/v1beta1connect/billing_subscription.go index 61a76429b..9f39f9c3b 100644 --- a/internal/api/v1beta1connect/billing_subscription.go +++ b/internal/api/v1beta1connect/billing_subscription.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/customer" @@ -13,8 +14,6 @@ import ( ) func (h *ConnectHandler) ListSubscriptions(ctx context.Context, request *connect.Request[frontierv1beta1.ListSubscriptionsRequest]) (*connect.Response[frontierv1beta1.ListSubscriptionsResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetOrgId() == "" { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -29,9 +28,7 @@ func (h *ConnectHandler) ListSubscriptions(ctx context.Context, request *connect Subscriptions: []*frontierv1beta1.Subscription{}, }), nil } - errorLogger.LogServiceError(ctx, request, "ListSubscriptions.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListSubscriptions.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID @@ -39,8 +36,6 @@ func (h *ConnectHandler) ListSubscriptions(ctx context.Context, request *connect if planID != "" { plan, err := h.planService.GetByID(ctx, planID) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListSubscriptions.GetByID", err, - "plan_id", planID) return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } planID = plan.ID @@ -53,18 +48,13 @@ func (h *ConnectHandler) ListSubscriptions(ctx context.Context, request *connect PlanID: planID, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListSubscriptions.List", err, - "billing_id", billingID, - "org_id", request.Msg.GetOrgId(), - "state", request.Msg.GetState(), - "plan_id", planID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListSubscriptions.List: billing_id=%s org_id=%s state=%s plan_id=%s: %w", + billingID, request.Msg.GetOrgId(), request.Msg.GetState(), planID, err)) } for _, v := range subscriptionList { subscriptionPB, err := transformSubscriptionToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListSubscriptions", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListSubscriptions: entity_id=%s: %w", v.ID, err)) } subscriptions = append(subscriptions, subscriptionPB) } @@ -80,19 +70,14 @@ func (h *ConnectHandler) ListSubscriptions(ctx context.Context, request *connect } func (h *ConnectHandler) GetSubscription(ctx context.Context, request *connect.Request[frontierv1beta1.GetSubscriptionRequest]) (*connect.Response[frontierv1beta1.GetSubscriptionResponse], error) { - errorLogger := NewErrorLogger() - subscription, err := h.subscriptionService.GetByID(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetSubscription.GetByID", err, - "subscription_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetSubscription.GetByID: subscription_id=%s: %w", request.Msg.GetId(), err)) } subscriptionPB, err := transformSubscriptionToPB(subscription) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetSubscription", subscription.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetSubscription: entity_id=%s: %w", subscription.ID, err)) } response := &frontierv1beta1.GetSubscriptionResponse{ Subscription: subscriptionPB, @@ -105,21 +90,14 @@ func (h *ConnectHandler) GetSubscription(ctx context.Context, request *connect.R } func (h *ConnectHandler) CancelSubscription(ctx context.Context, request *connect.Request[frontierv1beta1.CancelSubscriptionRequest]) (*connect.Response[frontierv1beta1.CancelSubscriptionResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.subscriptionService.Cancel(ctx, request.Msg.GetId(), request.Msg.GetImmediate()) if err != nil { - errorLogger.LogServiceError(ctx, request, "CancelSubscription.Cancel", err, - "subscription_id", request.Msg.GetId(), - "immediate", request.Msg.GetImmediate()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CancelSubscription.Cancel: subscription_id=%s immediate=%v: %w", request.Msg.GetId(), request.Msg.GetImmediate(), err)) } return connect.NewResponse(&frontierv1beta1.CancelSubscriptionResponse{}), nil } func (h *ConnectHandler) ChangeSubscription(ctx context.Context, request *connect.Request[frontierv1beta1.ChangeSubscriptionRequest]) (*connect.Response[frontierv1beta1.ChangeSubscriptionResponse], error) { - errorLogger := NewErrorLogger() - changeReq := subscription.ChangeRequest{ PlanID: request.Msg.GetPlan(), Immediate: request.Msg.GetImmediate(), @@ -147,12 +125,8 @@ func (h *ConnectHandler) ChangeSubscription(ctx context.Context, request *connec if errors.Is(err, subscription.ErrAlreadyOnSamePlan) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrAlreadyOnSamePlan) } - errorLogger.LogServiceError(ctx, request, "ChangeSubscription.ChangePlan", err, - "subscription_id", request.Msg.GetId(), - "plan_id", changeReq.PlanID, - "immediate", changeReq.Immediate, - "cancel_upcoming", changeReq.CancelUpcoming) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ChangeSubscription.ChangePlan: subscription_id=%s plan_id=%s immediate=%v cancel_upcoming=%v: %w", + request.Msg.GetId(), changeReq.PlanID, changeReq.Immediate, changeReq.CancelUpcoming, err)) } phasePb := &frontierv1beta1.Subscription_Phase{ diff --git a/internal/api/v1beta1connect/billing_usage.go b/internal/api/v1beta1connect/billing_usage.go index 13d382443..a4fd34e06 100644 --- a/internal/api/v1beta1connect/billing_usage.go +++ b/internal/api/v1beta1connect/billing_usage.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "reflect" "strings" "time" @@ -17,8 +18,6 @@ import ( ) func (h *ConnectHandler) CreateBillingUsage(ctx context.Context, request *connect.Request[frontierv1beta1.CreateBillingUsageRequest]) (*connect.Response[frontierv1beta1.CreateBillingUsageResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -28,9 +27,7 @@ func (h *ConnectHandler) CreateBillingUsage(ctx context.Context, request *connec if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "CreateBillingUsage.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateBillingUsage.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } createRequests := make([]usage.Usage, 0, len(request.Msg.GetUsages())) @@ -59,19 +56,14 @@ func (h *ConnectHandler) CreateBillingUsage(ctx context.Context, request *connec if errors.Is(err, credit.ErrAlreadyApplied) { return nil, connect.NewError(connect.CodeAlreadyExists, ErrAlreadyApplied) } - errorLogger.LogServiceError(ctx, request, "CreateBillingUsage.Report", err, - "billing_id", cust.ID, - "org_id", request.Msg.GetOrgId(), - "usage_count", len(createRequests)) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateBillingUsage.Report: billing_id=%s org_id=%s usage_count=%d: %w", + cust.ID, request.Msg.GetOrgId(), len(createRequests), err)) } return connect.NewResponse(&frontierv1beta1.CreateBillingUsageResponse{}), nil } func (h *ConnectHandler) ListBillingTransactions(ctx context.Context, request *connect.Request[frontierv1beta1.ListBillingTransactionsRequest]) (*connect.Response[frontierv1beta1.ListBillingTransactionsResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -85,9 +77,7 @@ func (h *ConnectHandler) ListBillingTransactions(ctx context.Context, request *c if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "ListBillingTransactions.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListBillingTransactions.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID @@ -110,18 +100,13 @@ func (h *ConnectHandler) ListBillingTransactions(ctx context.Context, request *c EndRange: endRange, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListBillingTransactions.List", err, - "org_id", request.Msg.GetOrgId(), - "billing_id", billingID, - "start_range", startRange, - "end_range", endRange) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListBillingTransactions.List: org_id=%s billing_id=%s start_range=%v end_range=%v: %w", + request.Msg.GetOrgId(), billingID, startRange, endRange, err)) } for _, v := range transactionsList { transactionPB, err := transformTransactionToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListBillingTransactions", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListBillingTransactions: entity_id=%s: %w", v.ID, err)) } transactions = append(transactions, transactionPB) } @@ -137,8 +122,6 @@ func (h *ConnectHandler) ListBillingTransactions(ctx context.Context, request *c } func (h *ConnectHandler) TotalDebitedTransactions(ctx context.Context, request *connect.Request[frontierv1beta1.TotalDebitedTransactionsRequest]) (*connect.Response[frontierv1beta1.TotalDebitedTransactionsResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -155,18 +138,14 @@ func (h *ConnectHandler) TotalDebitedTransactions(ctx context.Context, request * if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "TotalDebitedTransactions.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("TotalDebitedTransactions.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID debitAmount, err := h.creditService.GetTotalDebitedAmount(ctx, billingID) if err != nil { - errorLogger.LogServiceError(ctx, request, "TotalDebitedTransactions.GetTotalDebitedAmount", err, - "org_id", request.Msg.GetOrgId(), - "billing_id", billingID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("TotalDebitedTransactions.GetTotalDebitedAmount: org_id=%s billing_id=%s: %w", + request.Msg.GetOrgId(), billingID, err)) } return connect.NewResponse(&frontierv1beta1.TotalDebitedTransactionsResponse{ @@ -197,8 +176,6 @@ func transformTransactionToPB(t credit.Transaction) (*frontierv1beta1.BillingTra } func (h *ConnectHandler) RevertBillingUsage(ctx context.Context, request *connect.Request[frontierv1beta1.RevertBillingUsageRequest]) (*connect.Response[frontierv1beta1.RevertBillingUsageResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -208,9 +185,7 @@ func (h *ConnectHandler) RevertBillingUsage(ctx context.Context, request *connec if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "RevertBillingUsage.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RevertBillingUsage.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } if err := h.usageService.Revert(ctx, cust.ID, @@ -226,12 +201,8 @@ func (h *ConnectHandler) RevertBillingUsage(ctx context.Context, request *connec } else if errors.Is(err, credit.ErrAlreadyApplied) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "RevertBillingUsage.Revert", err, - "billing_id", cust.ID, - "org_id", request.Msg.GetOrgId(), - "usage_id", request.Msg.GetUsageId(), - "amount", request.Msg.GetAmount()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RevertBillingUsage.Revert: billing_id=%s org_id=%s usage_id=%s amount=%d: %w", + cust.ID, request.Msg.GetOrgId(), request.Msg.GetUsageId(), request.Msg.GetAmount(), err)) } return connect.NewResponse(&frontierv1beta1.RevertBillingUsageResponse{}), nil } diff --git a/internal/api/v1beta1connect/billing_usage_test.go b/internal/api/v1beta1connect/billing_usage_test.go index 3d6670cde..ed071ac3e 100644 --- a/internal/api/v1beta1connect/billing_usage_test.go +++ b/internal/api/v1beta1connect/billing_usage_test.go @@ -64,7 +64,7 @@ func TestConnectHandler_CreateBillingUsage(t *testing.T) { us.EXPECT().Report(mock.Anything, expectedUsages).Return(errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -409,7 +409,7 @@ func TestConnectHandler_ListBillingTransactions(t *testing.T) { }).Return(nil, errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { @@ -690,7 +690,7 @@ func TestConnectHandler_TotalDebitedTransactions(t *testing.T) { cs.EXPECT().GetTotalDebitedAmount(mock.Anything, "billing-123").Return(int64(0), errors.New("service error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { diff --git a/internal/api/v1beta1connect/billing_webhook.go b/internal/api/v1beta1connect/billing_webhook.go index 621f32f35..bc10ce327 100644 --- a/internal/api/v1beta1connect/billing_webhook.go +++ b/internal/api/v1beta1connect/billing_webhook.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/customer" @@ -11,8 +12,6 @@ import ( ) func (h *ConnectHandler) BillingWebhookCallback(ctx context.Context, request *connect.Request[frontierv1beta1.BillingWebhookCallbackRequest]) (*connect.Response[frontierv1beta1.BillingWebhookCallbackResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetProvider() != "stripe" { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBillingProviderNotSupported) } @@ -27,9 +26,7 @@ func (h *ConnectHandler) BillingWebhookCallback(ctx context.Context, request *co Name: request.Msg.GetProvider(), Body: request.Msg.GetBody(), }); err != nil { - errorLogger.LogServiceError(ctx, request, "BillingWebhookCallback.BillingWebhook", err, - "provider", request.Msg.GetProvider()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("BillingWebhookCallback.BillingWebhook: provider=%s: %w", request.Msg.GetProvider(), err)) } return connect.NewResponse(&frontierv1beta1.BillingWebhookCallbackResponse{}), nil } diff --git a/internal/api/v1beta1connect/billing_webhook_test.go b/internal/api/v1beta1connect/billing_webhook_test.go index 4c6cbb2f7..063ad4c14 100644 --- a/internal/api/v1beta1connect/billing_webhook_test.go +++ b/internal/api/v1beta1connect/billing_webhook_test.go @@ -61,7 +61,7 @@ func TestConnectHandler_BillingWebhookCallback(t *testing.T) { Body: []byte("webhook_body"), }), want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("service error"), errCode: connect.CodeInternal, }, { diff --git a/internal/api/v1beta1connect/deleter.go b/internal/api/v1beta1connect/deleter.go index 352841a38..6d14cfbb3 100644 --- a/internal/api/v1beta1connect/deleter.go +++ b/internal/api/v1beta1connect/deleter.go @@ -2,29 +2,22 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" frontierv1beta1 "github.com/raystack/frontier/proto/v1beta1" ) func (h *ConnectHandler) DeleteProject(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteProjectRequest]) (*connect.Response[frontierv1beta1.DeleteProjectResponse], error) { - errorLogger := NewErrorLogger() - if err := h.deleterService.DeleteProject(ctx, request.Msg.GetId()); err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteProject.DeleteProject", err, - "project_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProject.DeleteProject: project_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.DeleteProjectResponse{}), nil } func (h *ConnectHandler) DeleteOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteOrganizationRequest]) (*connect.Response[frontierv1beta1.DeleteOrganizationResponse], error) { - errorLogger := NewErrorLogger() - if err := h.deleterService.DeleteOrganization(ctx, request.Msg.GetId()); err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteOrganization.DeleteOrganization", err, - "organization_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganization.DeleteOrganization: organization_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.DeleteOrganizationResponse{}), nil } diff --git a/internal/api/v1beta1connect/deleter_test.go b/internal/api/v1beta1connect/deleter_test.go index e7496f7e7..351769c9e 100644 --- a/internal/api/v1beta1connect/deleter_test.go +++ b/internal/api/v1beta1connect/deleter_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "connectrpc.com/connect" @@ -40,7 +41,7 @@ func TestHandler_DeleteProject(t *testing.T) { Id: "some-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProject.DeleteProject: project_id=some-id: %w", errors.New("some error"))), }, } for _, tt := range tests { @@ -85,7 +86,7 @@ func TestHandler_DeleteOrganization(t *testing.T) { Id: "some-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganization.DeleteOrganization: organization_id=some-id: %w", errors.New("some_error"))), }, } for _, tt := range tests { diff --git a/internal/api/v1beta1connect/domain.go b/internal/api/v1beta1connect/domain.go index a5d717a63..0e0d5385b 100644 --- a/internal/api/v1beta1connect/domain.go +++ b/internal/api/v1beta1connect/domain.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/domain" @@ -14,8 +15,6 @@ import ( ) func (h *ConnectHandler) CreateOrganizationDomain(ctx context.Context, request *connect.Request[frontierv1beta1.CreateOrganizationDomainRequest]) (*connect.Response[frontierv1beta1.CreateOrganizationDomainResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -24,9 +23,7 @@ func (h *ConnectHandler) CreateOrganizationDomain(ctx context.Context, request * case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "CreateOrganizationDomain.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationDomain.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -39,10 +36,8 @@ func (h *ConnectHandler) CreateOrganizationDomain(ctx context.Context, request * case domain.ErrDuplicateKey: return nil, connect.NewError(connect.CodeAlreadyExists, ErrDomainAlreadyExists) default: - errorLogger.LogServiceError(ctx, request, "CreateOrganizationDomain.Create", err, - "org_id", request.Msg.GetOrgId(), - "domain_name", request.Msg.GetDomain()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationDomain.Create: org_id=%s domain_name=%s: %w", + request.Msg.GetOrgId(), request.Msg.GetDomain(), err)) } } @@ -51,8 +46,6 @@ func (h *ConnectHandler) CreateOrganizationDomain(ctx context.Context, request * } func (h *ConnectHandler) DeleteOrganizationDomain(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteOrganizationDomainRequest]) (*connect.Response[frontierv1beta1.DeleteOrganizationDomainResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -61,9 +54,7 @@ func (h *ConnectHandler) DeleteOrganizationDomain(ctx context.Context, request * case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "DeleteOrganizationDomain.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationDomain.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -72,10 +63,8 @@ func (h *ConnectHandler) DeleteOrganizationDomain(ctx context.Context, request * case domain.ErrNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrDomainNotFound) default: - errorLogger.LogServiceError(ctx, request, "DeleteOrganizationDomain.Delete", err, - "org_id", request.Msg.GetOrgId(), - "domain_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationDomain.Delete: org_id=%s domain_id=%s: %w", + request.Msg.GetOrgId(), request.Msg.GetId(), err)) } } @@ -83,8 +72,6 @@ func (h *ConnectHandler) DeleteOrganizationDomain(ctx context.Context, request * } func (h *ConnectHandler) GetOrganizationDomain(ctx context.Context, request *connect.Request[frontierv1beta1.GetOrganizationDomainRequest]) (*connect.Response[frontierv1beta1.GetOrganizationDomainResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -93,9 +80,7 @@ func (h *ConnectHandler) GetOrganizationDomain(ctx context.Context, request *con case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "GetOrganizationDomain.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationDomain.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -105,10 +90,8 @@ func (h *ConnectHandler) GetOrganizationDomain(ctx context.Context, request *con case domain.ErrNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrDomainNotFound) default: - errorLogger.LogServiceError(ctx, request, "GetOrganizationDomain.Get", err, - "org_id", request.Msg.GetOrgId(), - "domain_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationDomain.Get: org_id=%s domain_id=%s: %w", + request.Msg.GetOrgId(), request.Msg.GetId(), err)) } } @@ -117,12 +100,8 @@ func (h *ConnectHandler) GetOrganizationDomain(ctx context.Context, request *con } func (h *ConnectHandler) JoinOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.JoinOrganizationRequest]) (*connect.Response[frontierv1beta1.JoinOrganizationResponse], error) { - errorLogger := NewErrorLogger() - principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { - errorLogger.LogServiceError(ctx, request, "JoinOrganization.GetLoggedInPrincipal", err, - "org_id", request.Msg.GetOrgId()) return nil, connect.NewError(connect.CodeUnauthenticated, ErrUnauthenticated) } @@ -143,10 +122,8 @@ func (h *ConnectHandler) JoinOrganization(ctx context.Context, request *connect. case errors.Is(err, membership.ErrAlreadyMember): return nil, connect.NewError(connect.CodeAlreadyExists, err) default: - errorLogger.LogServiceError(ctx, request, "JoinOrganization.Join", err, - "org_id", request.Msg.GetOrgId(), - "principal_id", principal.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("JoinOrganization.Join: org_id=%s principal_id=%s: %w", + request.Msg.GetOrgId(), principal.ID, err)) } } @@ -154,8 +131,6 @@ func (h *ConnectHandler) JoinOrganization(ctx context.Context, request *connect. } func (h *ConnectHandler) VerifyOrganizationDomain(ctx context.Context, request *connect.Request[frontierv1beta1.VerifyOrganizationDomainRequest]) (*connect.Response[frontierv1beta1.VerifyOrganizationDomainResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -164,9 +139,7 @@ func (h *ConnectHandler) VerifyOrganizationDomain(ctx context.Context, request * case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "VerifyOrganizationDomain.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("VerifyOrganizationDomain.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -180,10 +153,8 @@ func (h *ConnectHandler) VerifyOrganizationDomain(ctx context.Context, request * case domain.ErrTXTrecordNotFound: return nil, connect.NewError(connect.CodeNotFound, ErrTXTRecordNotFound) default: - errorLogger.LogServiceError(ctx, request, "VerifyOrganizationDomain.VerifyDomain", err, - "org_id", request.Msg.GetOrgId(), - "domain_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("VerifyOrganizationDomain.VerifyDomain: org_id=%s domain_id=%s: %w", + request.Msg.GetOrgId(), request.Msg.GetId(), err)) } } @@ -191,8 +162,6 @@ func (h *ConnectHandler) VerifyOrganizationDomain(ctx context.Context, request * } func (h *ConnectHandler) ListOrganizationDomains(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationDomainsRequest]) (*connect.Response[frontierv1beta1.ListOrganizationDomainsResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -201,18 +170,14 @@ func (h *ConnectHandler) ListOrganizationDomains(ctx context.Context, request *c case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationDomains.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationDomains.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } domains, err := h.domainService.List(ctx, domain.Filter{OrgID: orgResp.ID, State: domain.Status(request.Msg.GetState())}) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationDomains.List", err, - "org_id", request.Msg.GetOrgId(), - "state", request.Msg.GetState()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationDomains.List: org_id=%s state=%s: %w", + request.Msg.GetOrgId(), request.Msg.GetState(), err)) } var domainPBs []*frontierv1beta1.Domain diff --git a/internal/api/v1beta1connect/domain_test.go b/internal/api/v1beta1connect/domain_test.go index 1620791d9..4289d5872 100644 --- a/internal/api/v1beta1connect/domain_test.go +++ b/internal/api/v1beta1connect/domain_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -79,7 +80,7 @@ func TestHandler_CreateOrganizationDomain(t *testing.T) { Domain: "raystack.org", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationDomain.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return not found error if org is disabled", @@ -135,7 +136,7 @@ func TestHandler_CreateOrganizationDomain(t *testing.T) { Domain: "raystack.org", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationDomain.Create: org_id=%s domain_name=%s: %w", testOrgID, "raystack.org", errors.New("domain service error"))), }, { name: "should create domain successfully", @@ -191,7 +192,7 @@ func TestHandler_DeleteOrganizationDomain(t *testing.T) { Id: testDomainID1, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationDomain.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return not found error if org is disabled", @@ -241,7 +242,7 @@ func TestHandler_DeleteOrganizationDomain(t *testing.T) { Id: testDomainID1, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationDomain.Delete: org_id=%s domain_id=%s: %w", testOrgID, testDomainID1, errors.New("domain service error"))), }, { name: "should delete domain successfully", @@ -294,7 +295,7 @@ func TestHandler_GetOrganizationDomain(t *testing.T) { Id: testDomainID1, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationDomain.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return not found error if org is disabled", @@ -344,7 +345,7 @@ func TestHandler_GetOrganizationDomain(t *testing.T) { Id: testDomainID1, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationDomain.Get: org_id=%s domain_id=%s: %w", testOrgID, testDomainID1, errors.New("domain service error"))), }, { name: "should get domain successfully", @@ -433,7 +434,7 @@ func TestHandler_JoinOrganization(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("JoinOrganization.Join: org_id=%s principal_id=%s: %w", testOrgID, testUserID, errors.New("domain service error"))), }, { name: "should join organization successfully", @@ -486,7 +487,7 @@ func TestHandler_ListOrganizationDomains(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationDomains.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return not found error if org is disabled", @@ -520,7 +521,7 @@ func TestHandler_ListOrganizationDomains(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationDomains.List: org_id=%s state=%s: %w", testOrgID, "", errors.New("domain service error"))), }, { name: "should list domains successfully", @@ -575,7 +576,7 @@ func TestHandler_VerifyOrganizationDomain(t *testing.T) { Id: testDomainID1, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("VerifyOrganizationDomain.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return not found error if org is disabled", @@ -651,7 +652,7 @@ func TestHandler_VerifyOrganizationDomain(t *testing.T) { Id: testDomainID1, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("VerifyOrganizationDomain.VerifyDomain: org_id=%s domain_id=%s: %w", testOrgID, testDomainID1, errors.New("domain service error"))), }, { name: "should verify domain successfully", diff --git a/internal/api/v1beta1connect/group.go b/internal/api/v1beta1connect/group.go index 314aec949..adb0913db 100644 --- a/internal/api/v1beta1connect/group.go +++ b/internal/api/v1beta1connect/group.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/audit" @@ -20,8 +21,6 @@ import ( ) func (h *ConnectHandler) ListGroups(ctx context.Context, request *connect.Request[frontierv1beta1.ListGroupsRequest]) (*connect.Response[frontierv1beta1.ListGroupsResponse], error) { - errorLogger := NewErrorLogger() - var groups []*frontierv1beta1.Group groupList, err := h.groupService.List(ctx, group.Filter{ SU: true, @@ -29,17 +28,13 @@ func (h *ConnectHandler) ListGroups(ctx context.Context, request *connect.Reques State: group.State(request.Msg.GetState()), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListGroups.List", err, - "org_id", request.Msg.GetOrgId(), - "state", request.Msg.GetState()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups.List: org_id=%s state=%s: %w", request.Msg.GetOrgId(), request.Msg.GetState(), err)) } for _, v := range groupList { groupPB, err := transformGroupToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListGroups", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups: entity_id=%s: %w", v.ID, err)) } groups = append(groups, &groupPB) @@ -49,8 +44,6 @@ func (h *ConnectHandler) ListGroups(ctx context.Context, request *connect.Reques } func (h *ConnectHandler) ListOrganizationGroups(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationGroupsRequest]) (*connect.Response[frontierv1beta1.ListOrganizationGroupsResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -59,9 +52,7 @@ func (h *ConnectHandler) ListOrganizationGroups(ctx context.Context, request *co case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationGroups.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationGroups.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -73,27 +64,19 @@ func (h *ConnectHandler) ListOrganizationGroups(ctx context.Context, request *co WithMemberCount: request.Msg.GetWithMemberCount(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationGroups.List", err, - "org_id", request.Msg.GetOrgId(), - "state", request.Msg.GetState(), - "group_ids", request.Msg.GetGroupIds(), - "with_member_count", request.Msg.GetWithMemberCount()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationGroups.List: org_id=%s state=%s: %w", request.Msg.GetOrgId(), request.Msg.GetState(), err)) } for _, v := range groupList { groupPB, err := transformGroupToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationGroups", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationGroups: entity_id=%s: %w", v.ID, err)) } if request.Msg.GetWithMembers() { groupUsers, err := h.listGroupUsers(ctx, v.ID, "") if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationGroups.listGroupUsers", err, - "group_id", v.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationGroups.listGroupUsers: group_id=%s: %w", v.ID, err)) } var groupUsersErr error groupPB.Users = utils.Filter(utils.Map(groupUsers, func(user user.User) *frontierv1beta1.User { @@ -107,9 +90,7 @@ func (h *ConnectHandler) ListOrganizationGroups(ctx context.Context, request *co return user != nil }) if groupUsersErr != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationGroups.transformUserToPB", groupUsersErr, - "group_id", v.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationGroups.transformUserToPB: group_id=%s: %w", v.ID, groupUsersErr)) } } @@ -135,8 +116,6 @@ func (h *ConnectHandler) listGroupUsers(ctx context.Context, groupID, roleID str } func (h *ConnectHandler) CreateGroup(ctx context.Context, request *connect.Request[frontierv1beta1.CreateGroupRequest]) (*connect.Response[frontierv1beta1.CreateGroupResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetBody() == nil { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -149,9 +128,7 @@ func (h *ConnectHandler) CreateGroup(ctx context.Context, request *connect.Reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "CreateGroup.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateGroup.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -183,18 +160,13 @@ func (h *ConnectHandler) CreateGroup(ctx context.Context, request *connect.Reque case errors.Is(err, user.ErrInvalidEmail): return nil, connect.NewError(connect.CodeUnauthenticated, ErrUnauthenticated) default: - errorLogger.LogServiceError(ctx, request, "CreateGroup.Create", err, - "org_id", request.Msg.GetOrgId(), - "group_name", name, - "group_title", requestBody.GetTitle()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateGroup.Create: org_id=%s group_name=%s: %w", request.Msg.GetOrgId(), name, err)) } } groupPB, err := transformGroupToPB(newGroup) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateGroup", newGroup.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateGroup: entity_id=%s: %w", newGroup.ID, err)) } audit.GetAuditor(ctx, request.Msg.GetOrgId()).Log(audit.GroupCreatedEvent, audit.GroupTarget(newGroup.ID)) @@ -202,8 +174,6 @@ func (h *ConnectHandler) CreateGroup(ctx context.Context, request *connect.Reque } func (h *ConnectHandler) GetGroup(ctx context.Context, request *connect.Request[frontierv1beta1.GetGroupRequest]) (*connect.Response[frontierv1beta1.GetGroupResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -212,9 +182,7 @@ func (h *ConnectHandler) GetGroup(ctx context.Context, request *connect.Request[ case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "GetGroup.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetGroup.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -224,24 +192,19 @@ func (h *ConnectHandler) GetGroup(ctx context.Context, request *connect.Request[ case errors.Is(err, group.ErrNotExist), errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound) default: - errorLogger.LogServiceError(ctx, request, "GetGroup.Get", err, - "group_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetGroup.Get: group_id=%s: %w", request.Msg.GetId(), err)) } } groupPB, err := transformGroupToPB(fetchedGroup) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetGroup", fetchedGroup.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetGroup: entity_id=%s: %w", fetchedGroup.ID, err)) } if request.Msg.GetWithMembers() { groupUsers, err := h.listGroupUsers(ctx, fetchedGroup.ID, "") if err != nil { - errorLogger.LogServiceError(ctx, request, "GetGroup.listGroupUsers", err, - "group_id", fetchedGroup.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetGroup.listGroupUsers: group_id=%s: %w", fetchedGroup.ID, err)) } var groupUsersErr error groupPB.Users = utils.Filter(utils.Map(groupUsers, func(user user.User) *frontierv1beta1.User { @@ -255,9 +218,7 @@ func (h *ConnectHandler) GetGroup(ctx context.Context, request *connect.Request[ return user != nil }) if groupUsersErr != nil { - errorLogger.LogServiceError(ctx, request, "GetGroup.transformUserToPB", groupUsersErr, - "group_id", fetchedGroup.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetGroup.transformUserToPB: group_id=%s: %w", fetchedGroup.ID, groupUsersErr)) } } @@ -265,8 +226,6 @@ func (h *ConnectHandler) GetGroup(ctx context.Context, request *connect.Request[ } func (h *ConnectHandler) UpdateGroup(ctx context.Context, request *connect.Request[frontierv1beta1.UpdateGroupRequest]) (*connect.Response[frontierv1beta1.UpdateGroupResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetBody() == nil { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -279,9 +238,7 @@ func (h *ConnectHandler) UpdateGroup(ctx context.Context, request *connect.Reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "UpdateGroup.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateGroup.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -307,17 +264,13 @@ func (h *ConnectHandler) UpdateGroup(ctx context.Context, request *connect.Reque case errors.Is(err, group.ErrInvalidDetail), errors.Is(err, organization.ErrInvalidUUID), errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogServiceError(ctx, request, "UpdateGroup.Update", err, - "group_id", request.Msg.GetId(), - "group_name", request.Msg.GetBody().GetName()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateGroup.Update: group_id=%s group_name=%s: %w", request.Msg.GetId(), request.Msg.GetBody().GetName(), err)) } } groupPB, err := transformGroupToPB(updatedGroup) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateGroup", updatedGroup.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateGroup: entity_id=%s: %w", updatedGroup.ID, err)) } audit.GetAuditor(ctx, orgResp.ID).Log(audit.GroupUpdatedEvent, audit.GroupTarget(updatedGroup.ID)) @@ -325,8 +278,6 @@ func (h *ConnectHandler) UpdateGroup(ctx context.Context, request *connect.Reque } func (h *ConnectHandler) ListGroupUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListGroupUsersRequest]) (*connect.Response[frontierv1beta1.ListGroupUsersResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -335,9 +286,7 @@ func (h *ConnectHandler) ListGroupUsers(ctx context.Context, request *connect.Re case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListGroupUsers.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -345,17 +294,13 @@ func (h *ConnectHandler) ListGroupUsers(ctx context.Context, request *connect.Re PrincipalType: schema.UserPrincipal, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListGroupUsers.ListPrincipalsByResource", err, - "group_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers.ListPrincipalsByResource: group_id=%s: %w", request.Msg.GetId(), err)) } userIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) users, err := h.userService.GetByIDs(ctx, userIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListGroupUsers.GetByIDs", err, - "group_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers.GetByIDs: group_id=%s: %w", request.Msg.GetId(), err)) } var userPBs []*frontierv1beta1.User @@ -363,8 +308,7 @@ func (h *ConnectHandler) ListGroupUsers(ctx context.Context, request *connect.Re for _, user := range users { userPb, err := transformUserToPB(user) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListGroupUsers", user.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers: entity_id=%s: %w", user.ID, err)) } userPBs = append(userPBs, userPb) } @@ -373,7 +317,6 @@ func (h *ConnectHandler) ListGroupUsers(ctx context.Context, request *connect.Re rolesPb := utils.Filter(utils.Map(m.Roles, func(r role.Role) *frontierv1beta1.Role { pb, err := transformRoleToPB(r) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListGroupUsers.transformRoleToPB", r.ID, err) return nil } return &pb @@ -393,8 +336,6 @@ func (h *ConnectHandler) ListGroupUsers(ctx context.Context, request *connect.Re } func (h *ConnectHandler) RemoveGroupUser(ctx context.Context, request *connect.Request[frontierv1beta1.RemoveGroupUserRequest]) (*connect.Response[frontierv1beta1.RemoveGroupUserResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -403,16 +344,11 @@ func (h *ConnectHandler) RemoveGroupUser(ctx context.Context, request *connect.R case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "RemoveGroupUser.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RemoveGroupUser.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } if err := h.membershipService.RemoveGroupMember(ctx, request.Msg.GetId(), request.Msg.GetUserId(), schema.UserPrincipal); err != nil { - errorLogger.LogServiceError(ctx, request, "RemoveGroupUser.RemoveGroupMember", err, - "group_id", request.Msg.GetId(), - "user_id", request.Msg.GetUserId()) switch { case errors.Is(err, group.ErrNotExist), errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID): @@ -428,15 +364,13 @@ func (h *ConnectHandler) RemoveGroupUser(ctx context.Context, request *connect.R case errors.Is(err, membership.ErrLastGroupOwnerRole): return nil, connect.NewError(connect.CodeInvalidArgument, ErrGroupMinOwnerCount) default: - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RemoveGroupUser.RemoveGroupMember: group_id=%s user_id=%s: %w", request.Msg.GetId(), request.Msg.GetUserId(), err)) } } return connect.NewResponse(&frontierv1beta1.RemoveGroupUserResponse{}), nil } func (h *ConnectHandler) SetGroupMemberRole(ctx context.Context, request *connect.Request[frontierv1beta1.SetGroupMemberRoleRequest]) (*connect.Response[frontierv1beta1.SetGroupMemberRoleResponse], error) { - errorLogger := NewErrorLogger() - orgID := request.Msg.GetOrgId() groupID := request.Msg.GetGroupId() principalID := request.Msg.GetPrincipalId() @@ -450,19 +384,11 @@ func (h *ConnectHandler) SetGroupMemberRole(ctx context.Context, request *connec case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "SetGroupMemberRole.GetOrg", err, - "org_id", orgID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SetGroupMemberRole.GetOrg: org_id=%s: %w", orgID, err)) } } if err := h.membershipService.SetGroupMemberRole(ctx, groupID, principalID, principalType, roleID); err != nil { - errorLogger.LogServiceError(ctx, request, "SetGroupMemberRole", err, - "group_id", groupID, - "principal_id", principalID, - "principal_type", principalType, - "role_id", roleID) - switch { case errors.Is(err, group.ErrNotExist), errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound) @@ -481,7 +407,7 @@ func (h *ConnectHandler) SetGroupMemberRole(ctx context.Context, request *connec case errors.Is(err, membership.ErrLastGroupOwnerRole): return nil, connect.NewError(connect.CodeFailedPrecondition, ErrLastGroupOwnerRole) default: - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SetGroupMemberRole: group_id=%s principal_id=%s: %w", groupID, principalID, err)) } } @@ -489,8 +415,6 @@ func (h *ConnectHandler) SetGroupMemberRole(ctx context.Context, request *connec } func (h *ConnectHandler) EnableGroup(ctx context.Context, request *connect.Request[frontierv1beta1.EnableGroupRequest]) (*connect.Response[frontierv1beta1.EnableGroupResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -499,9 +423,7 @@ func (h *ConnectHandler) EnableGroup(ctx context.Context, request *connect.Reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "EnableGroup.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableGroup.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } if err := h.groupService.Enable(ctx, request.Msg.GetId()); err != nil { @@ -509,17 +431,13 @@ func (h *ConnectHandler) EnableGroup(ctx context.Context, request *connect.Reque case errors.Is(err, group.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound) default: - errorLogger.LogServiceError(ctx, request, "EnableGroup.Enable", err, - "group_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableGroup.Enable: group_id=%s: %w", request.Msg.GetId(), err)) } } return connect.NewResponse(&frontierv1beta1.EnableGroupResponse{}), nil } func (h *ConnectHandler) DisableGroup(ctx context.Context, request *connect.Request[frontierv1beta1.DisableGroupRequest]) (*connect.Response[frontierv1beta1.DisableGroupResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -528,9 +446,7 @@ func (h *ConnectHandler) DisableGroup(ctx context.Context, request *connect.Requ case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "DisableGroup.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DisableGroup.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } if err := h.groupService.Disable(ctx, request.Msg.GetId()); err != nil { @@ -538,17 +454,13 @@ func (h *ConnectHandler) DisableGroup(ctx context.Context, request *connect.Requ case errors.Is(err, group.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound) default: - errorLogger.LogServiceError(ctx, request, "DisableGroup.Disable", err, - "group_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DisableGroup.Disable: group_id=%s: %w", request.Msg.GetId(), err)) } } return connect.NewResponse(&frontierv1beta1.DisableGroupResponse{}), nil } func (h *ConnectHandler) DeleteGroup(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteGroupRequest]) (*connect.Response[frontierv1beta1.DeleteGroupResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -557,9 +469,7 @@ func (h *ConnectHandler) DeleteGroup(ctx context.Context, request *connect.Reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrOrgNotFound) default: - errorLogger.LogServiceError(ctx, request, "DeleteGroup.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteGroup.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } if err := h.deleterService.DeleteGroup(ctx, request.Msg.GetId()); err != nil { @@ -567,9 +477,7 @@ func (h *ConnectHandler) DeleteGroup(ctx context.Context, request *connect.Reque case errors.Is(err, group.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound) default: - errorLogger.LogServiceError(ctx, request, "DeleteGroup.DeleteGroup", err, - "group_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteGroup.DeleteGroup: group_id=%s: %w", request.Msg.GetId(), err)) } } return connect.NewResponse(&frontierv1beta1.DeleteGroupResponse{}), nil diff --git a/internal/api/v1beta1connect/group_test.go b/internal/api/v1beta1connect/group_test.go index 43ee80e4a..8d3036861 100644 --- a/internal/api/v1beta1connect/group_test.go +++ b/internal/api/v1beta1connect/group_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -177,7 +178,7 @@ func TestHandler_ListGroups(t *testing.T) { OrgId: "9f256f86-31a3-11ec-8d3d-0242ac130003", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups.List: org_id=%s state=%s: %w", "9f256f86-31a3-11ec-8d3d-0242ac130003", "", errors.New("test-error"))), }, { name: "should return error while traversing group list if key is integer type", @@ -197,7 +198,7 @@ func TestHandler_ListGroups(t *testing.T) { OrgId: "some-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}"))), }, } for _, tt := range tests { @@ -383,7 +384,7 @@ func TestConnectHandler_CreateGroup(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: fmt.Errorf("CreateGroup.Create: org_id=%s group_name=%s: %w", testOrgID, "some-group", errors.New("test error")), }, { name: "should return success if group service return nil", @@ -504,7 +505,7 @@ func TestConnectHandler_GetGroup(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: fmt.Errorf("GetGroup.Get: group_id=%s: %w", someGroupID, errors.New("test error")), }, { name: "should return not found error if id is invalid", @@ -579,7 +580,7 @@ func TestConnectHandler_GetGroup(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: fmt.Errorf("GetGroup: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}")), }, } for _, tt := range tests { @@ -804,7 +805,7 @@ func TestConnectHandler_UpdateGroup(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: ErrInternalServerError, + wantErrMsg: fmt.Errorf("UpdateGroup.Update: group_id=%s group_name=%s: %w", someGroupID, "new-group", errors.New("test error")), }, { name: "should return success if updated by id and group service return nil error", @@ -1061,7 +1062,7 @@ func TestConnectHandler_ListGroupUsers(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers.ListPrincipalsByResource: group_id=%s: %w", someGroupID, errors.New("some error"))), }, { name: "should return error if metadata transformation fails in list of group users", @@ -1085,7 +1086,7 @@ func TestConnectHandler_ListGroupUsers(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]string"))), }, { name: "should return success if list group users and group service return nil error", @@ -1144,7 +1145,7 @@ func TestConnectHandler_ListGroupUsers(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers.ListPrincipalsByResource: group_id=%s: %w", someGroupID, errors.New("policy error"))), }, { name: "should return success with roles", @@ -1382,7 +1383,7 @@ func TestConnectHandler_RemoveGroupUser(t *testing.T) { UserId: randomID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("RemoveGroupUser.RemoveGroupMember: group_id=%s user_id=%s: %w", randomID, randomID, errors.New("unknown"))), }, { name: "should remove user successfully", @@ -1794,7 +1795,7 @@ func TestConnectHandler_SetGroupMemberRole(t *testing.T) { ms.EXPECT().SetGroupMemberRole(mock.Anything, someGroupID, somePrincipalID, schema.UserPrincipal, someRoleID).Return(errors.New("unknown")) }, request: baseRequest(), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("SetGroupMemberRole: group_id=%s principal_id=%s: %w", someGroupID, somePrincipalID, errors.New("unknown"))), }, { name: "should return success on valid request", diff --git a/internal/api/v1beta1connect/invitations.go b/internal/api/v1beta1connect/invitations.go index d80631738..e262d9734 100644 --- a/internal/api/v1beta1connect/invitations.go +++ b/internal/api/v1beta1connect/invitations.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "strings" "connectrpc.com/connect" @@ -16,8 +17,6 @@ import ( ) func (h *ConnectHandler) ListOrganizationInvitations(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationInvitationsRequest]) (*connect.Response[frontierv1beta1.ListOrganizationInvitationsResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -26,9 +25,7 @@ func (h *ConnectHandler) ListOrganizationInvitations(ctx context.Context, reques case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationInvitations.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationInvitations.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -37,18 +34,14 @@ func (h *ConnectHandler) ListOrganizationInvitations(ctx context.Context, reques UserID: request.Msg.GetUserId(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationInvitations.List", err, - "org_id", orgResp.ID, - "user_id", request.Msg.GetUserId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationInvitations.List: org_id=%s user_id=%s: %w", orgResp.ID, request.Msg.GetUserId(), err)) } var pbinvs []*frontierv1beta1.Invitation for _, inv := range invite { pbInv, err := transformInvitationToPB(inv) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationInvitations", inv.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationInvitations: entity_id=%s: %w", inv.ID.String(), err)) } pbinvs = append(pbinvs, pbInv) } @@ -59,22 +52,17 @@ func (h *ConnectHandler) ListOrganizationInvitations(ctx context.Context, reques } func (h *ConnectHandler) ListCurrentUserInvitations(ctx context.Context, request *connect.Request[frontierv1beta1.ListCurrentUserInvitationsRequest]) (*connect.Response[frontierv1beta1.ListCurrentUserInvitationsResponse], error) { - errorLogger := NewErrorLogger() - principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListCurrentUserInvitations.GetLoggedInPrincipal", err) return nil, connect.NewError(connect.CodeUnauthenticated, ErrUnauthenticated) } if principal.User == nil { - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, errors.New("principal user is nil")) } invites, err := h.invitationService.ListByUser(ctx, principal.User.Email) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListCurrentUserInvitations.ListByUser", err, - "user_email", principal.User.Email) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserInvitations.ListByUser: user_email=%s: %w", principal.User.Email, err)) } var invPBs []*frontierv1beta1.Invitation @@ -82,8 +70,7 @@ func (h *ConnectHandler) ListCurrentUserInvitations(ctx context.Context, request for _, inv := range invites { pbInv, err := transformInvitationToPB(inv) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListCurrentUserInvitations", inv.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserInvitations: entity_id=%s: %w", inv.ID.String(), err)) } invPBs = append(invPBs, pbInv) orgIds = append(orgIds, inv.OrgID) @@ -93,14 +80,11 @@ func (h *ConnectHandler) ListCurrentUserInvitations(ctx context.Context, request for _, org := range orgIds { orgResp, err := h.orgService.Get(ctx, org) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListCurrentUserInvitations.Get", err, - "org_id", org) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserInvitations.Get: org_id=%s: %w", org, err)) } orgPB, err := transformOrgToPB(orgResp) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListCurrentUserInvitations.transformOrgToPB", orgResp.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserInvitations.transformOrgToPB: entity_id=%s: %w", orgResp.ID, err)) } orgPBs = append(orgPBs, orgPB) } @@ -112,21 +96,16 @@ func (h *ConnectHandler) ListCurrentUserInvitations(ctx context.Context, request } func (h *ConnectHandler) ListUserInvitations(ctx context.Context, request *connect.Request[frontierv1beta1.ListUserInvitationsRequest]) (*connect.Response[frontierv1beta1.ListUserInvitationsResponse], error) { - errorLogger := NewErrorLogger() - invite, err := h.invitationService.ListByUser(ctx, request.Msg.GetId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListUserInvitations.ListByUser", err, - "user_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserInvitations.ListByUser: user_id=%s: %w", request.Msg.GetId(), err)) } var pbinvs []*frontierv1beta1.Invitation for _, inv := range invite { pbInv, err := transformInvitationToPB(inv) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListUserInvitations", inv.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserInvitations: entity_id=%s: %w", inv.ID.String(), err)) } pbinvs = append(pbinvs, pbInv) } @@ -137,8 +116,6 @@ func (h *ConnectHandler) ListUserInvitations(ctx context.Context, request *conne } func (h *ConnectHandler) CreateOrganizationInvitation(ctx context.Context, request *connect.Request[frontierv1beta1.CreateOrganizationInvitationRequest]) (*connect.Response[frontierv1beta1.CreateOrganizationInvitationResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -147,9 +124,7 @@ func (h *ConnectHandler) CreateOrganizationInvitation(ctx context.Context, reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "CreateOrganizationInvitation.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationInvitation.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -171,12 +146,7 @@ func (h *ConnectHandler) CreateOrganizationInvitation(ctx context.Context, reque if errors.Is(err, invitation.ErrAlreadyMember) { return nil, connect.NewError(connect.CodeAlreadyExists, ErrAlreadyMember) } - errorLogger.LogServiceError(ctx, request, "CreateOrganizationInvitation.Create", err, - "user_email", userID, - "org_id", orgResp.ID, - "role_ids", request.Msg.GetRoleIds(), - "group_ids", request.Msg.GetGroupIds()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationInvitation.Create: user_email=%s org_id=%s: %w", userID, orgResp.ID, err)) } createdInvitations = append(createdInvitations, inv) } @@ -185,8 +155,7 @@ func (h *ConnectHandler) CreateOrganizationInvitation(ctx context.Context, reque for _, inv := range createdInvitations { pbInv, err := transformInvitationToPB(inv) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateOrganizationInvitation", inv.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationInvitation: entity_id=%s: %w", inv.ID.String(), err)) } pbInvs = append(pbInvs, pbInv) } @@ -197,8 +166,6 @@ func (h *ConnectHandler) CreateOrganizationInvitation(ctx context.Context, reque } func (h *ConnectHandler) GetOrganizationInvitation(ctx context.Context, request *connect.Request[frontierv1beta1.GetOrganizationInvitationRequest]) (*connect.Response[frontierv1beta1.GetOrganizationInvitationResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -207,9 +174,7 @@ func (h *ConnectHandler) GetOrganizationInvitation(ctx context.Context, request case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "GetOrganizationInvitation.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationInvitation.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -220,15 +185,12 @@ func (h *ConnectHandler) GetOrganizationInvitation(ctx context.Context, request inv, err := h.invitationService.Get(ctx, inviteID) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetOrganizationInvitation.Get", err, - "invitation_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationInvitation.Get: invitation_id=%s: %w", request.Msg.GetId(), err)) } pbInv, err := transformInvitationToPB(inv) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetOrganizationInvitation", inv.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationInvitation: entity_id=%s: %w", inv.ID.String(), err)) } return connect.NewResponse(&frontierv1beta1.GetOrganizationInvitationResponse{ @@ -237,8 +199,6 @@ func (h *ConnectHandler) GetOrganizationInvitation(ctx context.Context, request } func (h *ConnectHandler) AcceptOrganizationInvitation(ctx context.Context, request *connect.Request[frontierv1beta1.AcceptOrganizationInvitationRequest]) (*connect.Response[frontierv1beta1.AcceptOrganizationInvitationResponse], error) { - errorLogger := NewErrorLogger() - inviteID, err := uuid.Parse(request.Msg.GetId()) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) @@ -263,10 +223,7 @@ func (h *ConnectHandler) AcceptOrganizationInvitation(ctx context.Context, reque case errors.Is(err, membership.ErrAlreadyMember): return nil, connect.NewError(connect.CodeAlreadyExists, err) default: - errorLogger.LogServiceError(ctx, request, "AcceptOrganizationInvitation.Accept", err, - "invitation_id", request.Msg.GetId(), - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AcceptOrganizationInvitation.Accept: invitation_id=%s org_id=%s: %w", request.Msg.GetId(), request.Msg.GetOrgId(), err)) } } @@ -274,8 +231,6 @@ func (h *ConnectHandler) AcceptOrganizationInvitation(ctx context.Context, reque } func (h *ConnectHandler) DeleteOrganizationInvitation(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteOrganizationInvitationRequest]) (*connect.Response[frontierv1beta1.DeleteOrganizationInvitationResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -284,9 +239,7 @@ func (h *ConnectHandler) DeleteOrganizationInvitation(ctx context.Context, reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "DeleteOrganizationInvitation.Get", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationInvitation.Get: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } @@ -296,10 +249,7 @@ func (h *ConnectHandler) DeleteOrganizationInvitation(ctx context.Context, reque } if err := h.invitationService.Delete(ctx, inviteID); err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteOrganizationInvitation.Delete", err, - "invitation_id", request.Msg.GetId(), - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationInvitation.Delete: invitation_id=%s org_id=%s: %w", request.Msg.GetId(), request.Msg.GetOrgId(), err)) } return connect.NewResponse(&frontierv1beta1.DeleteOrganizationInvitationResponse{}), nil diff --git a/internal/api/v1beta1connect/invitations_test.go b/internal/api/v1beta1connect/invitations_test.go index c82902f90..da97fbfbd 100644 --- a/internal/api/v1beta1connect/invitations_test.go +++ b/internal/api/v1beta1connect/invitations_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -87,7 +88,7 @@ func TestHandler_ListOrganizationInvitations(t *testing.T) { request: connect.NewRequest(&frontierv1beta1.ListOrganizationInvitationsRequest{ OrgId: testOrgID, }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationInvitations.List: org_id=%s user_id=%s: %w", testOrgID, "", errors.New("new-error"))), want: nil, }, { @@ -161,7 +162,7 @@ func TestHandler_ListCurrentUserInvitations(t *testing.T) { is.EXPECT().ListByUser(mock.AnythingOfType("context.backgroundCtx"), testUserEmail).Return(nil, errors.New("new-error")) }, request: connect.NewRequest(&frontierv1beta1.ListCurrentUserInvitationsRequest{}), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserInvitations.ListByUser: user_email=%s: %w", testUserEmail, errors.New("new-error"))), want: nil, }, { @@ -254,7 +255,7 @@ func TestHandler_ListUserInvitations(t *testing.T) { request: connect.NewRequest(&frontierv1beta1.ListUserInvitationsRequest{ Id: testUserEmail, }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserInvitations.ListByUser: user_id=%s: %w", testUserEmail, errors.New("new-error"))), want: nil, }, { @@ -383,7 +384,7 @@ func TestHandler_CreateOrganizationInvitation(t *testing.T) { GroupIds: []string{randomGroupID}, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationInvitation.Create: user_email=%s org_id=%s: %w", testUserEmail, testOrgID, errors.New("test error"))), }, { name: "should create a new invitation with the default expiration date", @@ -487,7 +488,7 @@ func TestHandler_GetOrganizationInvitation(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationInvitation.Get: invitation_id=%s: %w", testInvitation1ID.String(), errors.New("test error"))), }, { name: "should return an error if the invitation is not found", @@ -500,7 +501,7 @@ func TestHandler_GetOrganizationInvitation(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationInvitation.Get: invitation_id=%s: %w", testInvitation1ID.String(), invitation.ErrNotFound)), }, } @@ -564,7 +565,7 @@ func TestHandler_AcceptOrganizationInvitation(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("AcceptOrganizationInvitation.Accept: invitation_id=%s org_id=%s: %w", testInvitation1ID.String(), testOrgID, errors.New("test error"))), }, { name: "should return error if invitation is expired", @@ -635,7 +636,7 @@ func TestHandler_DeleteOrganizationInvitation(t *testing.T) { OrgId: randomOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationInvitation.Delete: invitation_id=%s org_id=%s: %w", testInvitation1ID.String(), randomOrgID, errors.New("test error"))), }, { name: "should delete an invitation on success", diff --git a/internal/api/v1beta1connect/kyc.go b/internal/api/v1beta1connect/kyc.go index 41623b298..1865d1e96 100644 --- a/internal/api/v1beta1connect/kyc.go +++ b/internal/api/v1beta1connect/kyc.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "strconv" "connectrpc.com/connect" @@ -13,8 +14,6 @@ import ( ) func (h *ConnectHandler) SetOrganizationKyc(ctx context.Context, request *connect.Request[frontierv1beta1.SetOrganizationKycRequest]) (*connect.Response[frontierv1beta1.SetOrganizationKycResponse], error) { - errorLogger := NewErrorLogger() - orgKyc, err := h.orgKycService.SetKyc(ctx, kyc.KYC{ OrgID: request.Msg.GetOrgId(), Status: request.Msg.GetStatus(), @@ -29,11 +28,7 @@ func (h *ConnectHandler) SetOrganizationKyc(ctx context.Context, request *connec case errors.Is(err, kyc.ErrOrgDoesntExist): return nil, connect.NewError(connect.CodeInvalidArgument, kyc.ErrOrgDoesntExist) default: - errorLogger.LogServiceError(ctx, request, "SetOrganizationKyc.SetKyc", err, - "org_id", request.Msg.GetOrgId(), - "status", request.Msg.GetStatus(), - "link", request.Msg.GetLink()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SetOrganizationKyc.SetKyc: org_id=%s status=%v: %w", request.Msg.GetOrgId(), request.Msg.GetStatus(), err)) } } @@ -48,8 +43,6 @@ func (h *ConnectHandler) SetOrganizationKyc(ctx context.Context, request *connec } func (h *ConnectHandler) GetOrganizationKyc(ctx context.Context, request *connect.Request[frontierv1beta1.GetOrganizationKycRequest]) (*connect.Response[frontierv1beta1.GetOrganizationKycResponse], error) { - errorLogger := NewErrorLogger() - orgKyc, err := h.orgKycService.GetKyc(ctx, request.Msg.GetOrgId()) if err != nil { switch { @@ -61,25 +54,20 @@ func (h *ConnectHandler) GetOrganizationKyc(ctx context.Context, request *connec Link: "", } default: - errorLogger.LogServiceError(ctx, request, "GetOrganizationKyc.GetKyc", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationKyc.GetKyc: org_id=%s: %w", request.Msg.GetOrgId(), err)) } } return connect.NewResponse(&frontierv1beta1.GetOrganizationKycResponse{OrganizationKyc: transformOrgKycToPB(orgKyc)}), nil } func (h *ConnectHandler) ListOrganizationsKyc(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationsKycRequest]) (*connect.Response[frontierv1beta1.ListOrganizationsKycResponse], error) { - errorLogger := NewErrorLogger() - orgKycs, err := h.orgKycService.ListKycs(ctx) if err != nil { switch { case errors.Is(err, kyc.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, kyc.ErrNotExist) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationsKyc.ListKycs", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsKyc.ListKycs: %w", err)) } } resp := make([]*frontierv1beta1.OrganizationKyc, len(orgKycs)) diff --git a/internal/api/v1beta1connect/kyc_test.go b/internal/api/v1beta1connect/kyc_test.go index cd0523952..725211370 100644 --- a/internal/api/v1beta1connect/kyc_test.go +++ b/internal/api/v1beta1connect/kyc_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "connectrpc.com/connect" @@ -86,7 +87,7 @@ func TestSetOrganizationKyc(t *testing.T) { }), mockError: errors.New("internal error"), expectError: true, - expectedError: connect.NewError(connect.CodeInternal, errors.New("internal server error")), + expectedError: connect.NewError(connect.CodeInternal, fmt.Errorf("SetOrganizationKyc.SetKyc: org_id=%s status=%v: %w", "valid-org-id", true, errors.New("internal error"))), }, } @@ -241,7 +242,7 @@ func TestListOrganizationsKyc(t *testing.T) { mockService: mocks.NewKycService(t), mockResponse: nil, mockError: errors.New("internal error"), - expectError: connect.NewError(connect.CodeInternal, errors.New("internal server error")), + expectError: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsKyc.ListKycs: %w", errors.New("internal error"))), expectNilResp: true, }, } diff --git a/internal/api/v1beta1connect/metaschema.go b/internal/api/v1beta1connect/metaschema.go index b2a016bd3..64f883ef0 100644 --- a/internal/api/v1beta1connect/metaschema.go +++ b/internal/api/v1beta1connect/metaschema.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "strings" "connectrpc.com/connect" @@ -19,12 +20,9 @@ var ( ) func (h *ConnectHandler) ListMetaSchemas(ctx context.Context, req *connect.Request[frontierv1beta1.ListMetaSchemasRequest]) (*connect.Response[frontierv1beta1.ListMetaSchemasResponse], error) { - errorLogger := NewErrorLogger() - metaschemasList, err := h.metaSchemaService.List(ctx) if err != nil { - errorLogger.LogServiceError(ctx, req, "ListMetaSchemas.List", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListMetaSchemas.List: %w", err)) } var metaschemas []*frontierv1beta1.MetaSchema @@ -39,8 +37,6 @@ func (h *ConnectHandler) ListMetaSchemas(ctx context.Context, req *connect.Reque } func (h *ConnectHandler) CreateMetaSchema(ctx context.Context, req *connect.Request[frontierv1beta1.CreateMetaSchemaRequest]) (*connect.Response[frontierv1beta1.CreateMetaSchemaResponse], error) { - errorLogger := NewErrorLogger() - if req.Msg.GetBody() == nil { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -58,9 +54,7 @@ func (h *ConnectHandler) CreateMetaSchema(ctx context.Context, req *connect.Requ case errors.Is(err, metaschema.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogServiceError(ctx, req, "CreateMetaSchema.Create", err, - "metaschema_name", req.Msg.GetBody().GetName()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateMetaSchema.Create: metaschema_name=%s: %w", req.Msg.GetBody().GetName(), err)) } } @@ -71,8 +65,6 @@ func (h *ConnectHandler) CreateMetaSchema(ctx context.Context, req *connect.Requ } func (h *ConnectHandler) GetMetaSchema(ctx context.Context, req *connect.Request[frontierv1beta1.GetMetaSchemaRequest]) (*connect.Response[frontierv1beta1.GetMetaSchemaResponse], error) { - errorLogger := NewErrorLogger() - id := req.Msg.GetId() if strings.TrimSpace(id) == "" { return nil, connect.NewError(connect.CodeNotFound, ErrMetaschemaNotFound) @@ -84,9 +76,7 @@ func (h *ConnectHandler) GetMetaSchema(ctx context.Context, req *connect.Request case errors.Is(err, metaschema.ErrNotExist), errors.Is(err, metaschema.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrMetaschemaNotFound) default: - errorLogger.LogServiceError(ctx, req, "GetMetaSchema.Get", err, - "metaschema_id", id) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetMetaSchema.Get: metaschema_id=%s: %w", id, err)) } } @@ -97,8 +87,6 @@ func (h *ConnectHandler) GetMetaSchema(ctx context.Context, req *connect.Request } func (h *ConnectHandler) UpdateMetaSchema(ctx context.Context, req *connect.Request[frontierv1beta1.UpdateMetaSchemaRequest]) (*connect.Response[frontierv1beta1.UpdateMetaSchemaResponse], error) { - errorLogger := NewErrorLogger() - id := req.Msg.GetId() if strings.TrimSpace(id) == "" { return nil, connect.NewError(connect.CodeNotFound, ErrMetaschemaNotFound) @@ -121,10 +109,7 @@ func (h *ConnectHandler) UpdateMetaSchema(ctx context.Context, req *connect.Requ case errors.Is(err, metaschema.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogServiceError(ctx, req, "UpdateMetaSchema.Update", err, - "metaschema_id", id, - "metaschema_name", req.Msg.GetBody().GetName()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateMetaSchema.Update: metaschema_id=%s metaschema_name=%s: %w", id, req.Msg.GetBody().GetName(), err)) } } @@ -135,8 +120,6 @@ func (h *ConnectHandler) UpdateMetaSchema(ctx context.Context, req *connect.Requ } func (h *ConnectHandler) DeleteMetaSchema(ctx context.Context, req *connect.Request[frontierv1beta1.DeleteMetaSchemaRequest]) (*connect.Response[frontierv1beta1.DeleteMetaSchemaResponse], error) { - errorLogger := NewErrorLogger() - id := req.Msg.GetId() if strings.TrimSpace(id) == "" { return nil, connect.NewError(connect.CodeNotFound, ErrMetaschemaNotFound) @@ -149,9 +132,7 @@ func (h *ConnectHandler) DeleteMetaSchema(ctx context.Context, req *connect.Requ errors.Is(err, metaschema.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrMetaschemaNotFound) default: - errorLogger.LogServiceError(ctx, req, "DeleteMetaSchema.Delete", err, - "metaschema_id", id) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteMetaSchema.Delete: metaschema_id=%s: %w", id, err)) } } diff --git a/internal/api/v1beta1connect/metaschema_test.go b/internal/api/v1beta1connect/metaschema_test.go index e3566f628..f619b4ab0 100644 --- a/internal/api/v1beta1connect/metaschema_test.go +++ b/internal/api/v1beta1connect/metaschema_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "time" @@ -57,7 +58,7 @@ func TestConnectHandler_ListMetaSchemas(t *testing.T) { }, req: connect.NewRequest(&frontierv1beta1.ListMetaSchemasRequest{}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListMetaSchemas.List: %w", errors.New("service error"))), }, { name: "should return empty list when no metaschemas exist", @@ -244,7 +245,7 @@ func TestConnectHandler_GetMetaSchema(t *testing.T) { }, req: connect.NewRequest(&frontierv1beta1.GetMetaSchemaRequest{Id: "test_id"}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetMetaSchema.Get: metaschema_id=%s: %w", "test_id", errors.New("service error"))), }, } @@ -409,7 +410,7 @@ func TestConnectHandler_DeleteMetaSchema(t *testing.T) { }, req: connect.NewRequest(&frontierv1beta1.DeleteMetaSchemaRequest{Id: "test_id"}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteMetaSchema.Delete: metaschema_id=%s: %w", "test_id", errors.New("service error"))), }, } diff --git a/internal/api/v1beta1connect/namespace.go b/internal/api/v1beta1connect/namespace.go index 11dbe5cd9..36dd2fb74 100644 --- a/internal/api/v1beta1connect/namespace.go +++ b/internal/api/v1beta1connect/namespace.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/namespace" @@ -11,21 +12,17 @@ import ( ) func (h *ConnectHandler) ListNamespaces(ctx context.Context, request *connect.Request[frontierv1beta1.ListNamespacesRequest]) (*connect.Response[frontierv1beta1.ListNamespacesResponse], error) { - errorLogger := NewErrorLogger() - var namespaces []*frontierv1beta1.Namespace nsList, err := h.namespaceService.List(ctx) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListNamespaces.List", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListNamespaces.List: %w", err)) } for _, ns := range nsList { nsPB, err := transformNamespaceToPB(ns) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListNamespaces", ns.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListNamespaces: entity_id=%s: %w", ns.ID, err)) } namespaces = append(namespaces, &nsPB) @@ -35,8 +32,6 @@ func (h *ConnectHandler) ListNamespaces(ctx context.Context, request *connect.Re } func (h *ConnectHandler) GetNamespace(ctx context.Context, request *connect.Request[frontierv1beta1.GetNamespaceRequest]) (*connect.Response[frontierv1beta1.GetNamespaceResponse], error) { - errorLogger := NewErrorLogger() - fetchedNS, err := h.namespaceService.Get(ctx, request.Msg.GetId()) if err != nil { switch { @@ -44,16 +39,13 @@ func (h *ConnectHandler) GetNamespace(ctx context.Context, request *connect.Requ errors.Is(err, namespace.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "GetNamespace.Get", err, - "namespace_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetNamespace.Get: namespace_id=%s: %w", request.Msg.GetId(), err)) } } nsPB, err := transformNamespaceToPB(fetchedNS) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetNamespace", fetchedNS.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetNamespace: entity_id=%s: %w", fetchedNS.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetNamespaceResponse{Namespace: &nsPB}), nil diff --git a/internal/api/v1beta1connect/namespace_test.go b/internal/api/v1beta1connect/namespace_test.go index 410e541d8..08b9ae662 100644 --- a/internal/api/v1beta1connect/namespace_test.go +++ b/internal/api/v1beta1connect/namespace_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "sort" "strings" "testing" @@ -54,7 +55,7 @@ func TestHandler_ListNamespaces(t *testing.T) { }, request: connect.NewRequest(&frontierv1beta1.ListNamespacesRequest{}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListNamespaces.List: %w", errors.New("test error"))), }, { name: "should return success if namespace service return nil error", @@ -126,7 +127,7 @@ func TestHandler_GetNamespace(t *testing.T) { Id: testNSID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetNamespace.Get: namespace_id=%s: %w", testNSID, errors.New("test error"))), }, { name: "should return not found error if namespace id is empty", diff --git a/internal/api/v1beta1connect/organization.go b/internal/api/v1beta1connect/organization.go index abeb3c91b..3f87ee008 100644 --- a/internal/api/v1beta1connect/organization.go +++ b/internal/api/v1beta1connect/organization.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" @@ -30,8 +31,6 @@ var ( ) func (h *ConnectHandler) GetOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.GetOrganizationRequest]) (*connect.Response[frontierv1beta1.GetOrganizationResponse], error) { - errorLogger := NewErrorLogger() - fetchedOrg, err := h.orgService.GetRaw(ctx, request.Msg.GetId()) if err != nil { switch { @@ -40,16 +39,13 @@ func (h *ConnectHandler) GetOrganization(ctx context.Context, request *connect.R case errors.Is(err, organization.ErrInvalidUUID): return nil, connect.NewError(connect.CodeInvalidArgument, err) default: - errorLogger.LogServiceError(ctx, request, "GetOrganization.GetRaw", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganization.GetRaw: org_id=%s: %w", request.Msg.GetId(), err)) } } orgPB, err := transformOrgToPB(fetchedOrg) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetOrganization", fetchedOrg.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganization: entity_id=%s: %w", fetchedOrg.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetOrganizationResponse{ @@ -79,7 +75,6 @@ func (h *ConnectHandler) ListAllOrganizations(ctx context.Context, request *conn } func (h *ConnectHandler) searchOrgs(ctx context.Context, req connect.AnyRequest, userID, stateStr string, pageNum, pageSize int32, rpcName string) ([]*frontierv1beta1.Organization, int32, error) { - errorLogger := NewErrorLogger() paginate := pagination.NewPagination(pageNum, pageSize) filter := organization.Filter{ State: organization.State(stateStr), @@ -91,17 +86,14 @@ func (h *ConnectHandler) searchOrgs(ctx context.Context, req connect.AnyRequest, orgList, err := h.orgService.List(ctx, filter) if err != nil { - errorLogger.LogServiceError(ctx, req, rpcName+".List", err, - "state", stateStr, "user_id", userID) - return nil, 0, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, 0, connect.NewError(connect.CodeInternal, fmt.Errorf("%s.List: state=%s user_id=%s: %w", rpcName, stateStr, userID, err)) } orgs := make([]*frontierv1beta1.Organization, 0, len(orgList)) for _, v := range orgList { orgPB, err := transformOrgToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, req, rpcName, v.ID, err) - return nil, 0, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, 0, connect.NewError(connect.CodeInternal, fmt.Errorf("%s: entity_id=%s: %w", rpcName, v.ID, err)) } orgs = append(orgs, orgPB) } @@ -139,17 +131,13 @@ func (h *ConnectHandler) CreateOrganization(ctx context.Context, request *connec "org_title", request.Msg.GetBody().GetTitle()) return nil, connect.NewError(connect.CodePermissionDenied, ErrUnauthorized) default: - errorLogger.LogServiceError(ctx, request, "CreateOrganization.Create", err, - "org_name", request.Msg.GetBody().GetName(), - "org_title", request.Msg.GetBody().GetTitle()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganization.Create: org_name=%s org_title=%s: %w", request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), err)) } } orgPB, err := transformOrgToPB(newOrg) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateOrganization", newOrg.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganization: entity_id=%s: %w", newOrg.ID, err)) } if err := audit.GetAuditor(ctx, newOrg.ID).LogWithAttrs(audit.OrgCreatedEvent, audit.OrgTarget(newOrg.ID), map[string]string{ @@ -163,8 +151,6 @@ func (h *ConnectHandler) CreateOrganization(ctx context.Context, request *connec } func (h *ConnectHandler) AdminCreateOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.AdminCreateOrganizationRequest]) (*connect.Response[frontierv1beta1.AdminCreateOrganizationResponse], error) { - errorLogger := NewErrorLogger() - metaDataMap := metadata.Build(request.Msg.GetBody().GetMetadata().AsMap()) if err := h.metaSchemaService.Validate(metaDataMap, orgMetaSchema); err != nil { @@ -186,18 +172,13 @@ func (h *ConnectHandler) AdminCreateOrganization(ctx context.Context, request *c case errors.Is(err, organization.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogServiceError(ctx, request, "AdminCreateOrganization.AdminCreate", err, - "org_name", request.Msg.GetBody().GetName(), - "org_title", request.Msg.GetBody().GetTitle(), - "owner_email", request.Msg.GetBody().GetOrgOwnerEmail()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AdminCreateOrganization.AdminCreate: org_name=%s org_title=%s owner_email=%s: %w", request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetOrgOwnerEmail(), err)) } } orgPB, err := transformOrgToPB(newOrg) if err != nil { - errorLogger.LogTransformError(ctx, request, "AdminCreateOrganization", newOrg.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AdminCreateOrganization: entity_id=%s: %w", newOrg.ID, err)) } audit.GetAuditor(ctx, newOrg.ID).LogWithAttrs(audit.OrgCreatedEvent, audit.OrgTarget(newOrg.ID), map[string]string{ @@ -208,8 +189,6 @@ func (h *ConnectHandler) AdminCreateOrganization(ctx context.Context, request *c } func (h *ConnectHandler) UpdateOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.UpdateOrganizationRequest]) (*connect.Response[frontierv1beta1.UpdateOrganizationResponse], error) { - errorLogger := NewErrorLogger() - if request.Msg.GetBody() == nil { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } @@ -245,18 +224,13 @@ func (h *ConnectHandler) UpdateOrganization(ctx context.Context, request *connec case errors.Is(err, organization.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogServiceError(ctx, request, "UpdateOrganization.Update", err, - "org_id", request.Msg.GetId(), - "org_name", request.Msg.GetBody().GetName(), - "org_title", request.Msg.GetBody().GetTitle()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateOrganization.Update: org_id=%s org_name=%s org_title=%s: %w", request.Msg.GetId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), err)) } } orgPB, err := transformOrgToPB(updatedOrg) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateOrganization", updatedOrg.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateOrganization: entity_id=%s: %w", updatedOrg.ID, err)) } audit.GetAuditor(ctx, updatedOrg.ID).Log(audit.OrgUpdatedEvent, audit.OrgTarget(updatedOrg.ID)) @@ -264,8 +238,6 @@ func (h *ConnectHandler) UpdateOrganization(ctx context.Context, request *connec } func (h *ConnectHandler) ListOrganizationProjects(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationProjectsRequest]) (*connect.Response[frontierv1beta1.ListOrganizationProjectsResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetId()) if err != nil { switch { @@ -274,9 +246,7 @@ func (h *ConnectHandler) ListOrganizationProjects(ctx context.Context, request * case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationProjects.Get", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationProjects.Get: org_id=%s: %w", request.Msg.GetId(), err)) } } @@ -285,18 +255,14 @@ func (h *ConnectHandler) ListOrganizationProjects(ctx context.Context, request * WithMemberCount: request.Msg.GetWithMemberCount(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationProjects.List", err, - "org_id", orgResp.ID, - "with_member_count", request.Msg.GetWithMemberCount()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationProjects.List: org_id=%s with_member_count=%v: %w", orgResp.ID, request.Msg.GetWithMemberCount(), err)) } var projectPB []*frontierv1beta1.Project for _, rel := range projects { u, err := transformProjectToPB(rel) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationProjects", rel.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationProjects: entity_id=%s: %w", rel.ID, err)) } projectPB = append(projectPB, u) @@ -306,8 +272,6 @@ func (h *ConnectHandler) ListOrganizationProjects(ctx context.Context, request * } func (h *ConnectHandler) ListOrganizationAdmins(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationAdminsRequest]) (*connect.Response[frontierv1beta1.ListOrganizationAdminsResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetId()) if err != nil { switch { @@ -316,18 +280,13 @@ func (h *ConnectHandler) ListOrganizationAdmins(ctx context.Context, request *co case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationAdmins.Get", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins.Get: org_id=%s: %w", request.Msg.GetId(), err)) } } ownerRole, err := h.roleService.Get(ctx, organization.AdminRole) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationAdmins.roleService.Get", err, - "org_id", orgResp.ID, - "role", organization.AdminRole) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins.roleService.Get: org_id=%s role=%s: %w", orgResp.ID, organization.AdminRole, err)) } members, err := h.membershipService.ListPrincipalsByResource(ctx, orgResp.ID, schema.OrganizationNamespace, membership.MemberFilter{ @@ -335,25 +294,20 @@ func (h *ConnectHandler) ListOrganizationAdmins(ctx context.Context, request *co RoleIDs: []string{ownerRole.ID}, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationAdmins.ListPrincipalsByResource", err, - "org_id", orgResp.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins.ListPrincipalsByResource: org_id=%s: %w", orgResp.ID, err)) } adminIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) admins, err := h.userService.GetByIDs(ctx, adminIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationAdmins.GetByIDs", err, - "org_id", orgResp.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins.GetByIDs: org_id=%s: %w", orgResp.ID, err)) } var adminsPB []*frontierv1beta1.User for _, user := range admins { u, err := transformUserToPB(user) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationAdmins", user.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins: entity_id=%s: %w", user.ID, err)) } adminsPB = append(adminsPB, u) @@ -363,8 +317,6 @@ func (h *ConnectHandler) ListOrganizationAdmins(ctx context.Context, request *co } func (h *ConnectHandler) ListOrganizationUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationUsersRequest]) (*connect.Response[frontierv1beta1.ListOrganizationUsersResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetId()) if err != nil { switch { @@ -373,9 +325,7 @@ func (h *ConnectHandler) ListOrganizationUsers(ctx context.Context, request *con case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationUsers.Get", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationUsers.Get: org_id=%s: %w", request.Msg.GetId(), err)) } } @@ -384,18 +334,13 @@ func (h *ConnectHandler) ListOrganizationUsers(ctx context.Context, request *con RoleIDs: request.Msg.GetRoleIds(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationUsers.ListPrincipalsByResource", err, - "org_id", orgResp.ID, - "role_ids", request.Msg.GetRoleIds()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationUsers.ListPrincipalsByResource: org_id=%s role_ids=%v: %w", orgResp.ID, request.Msg.GetRoleIds(), err)) } userIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) users, err := h.userService.GetByIDs(ctx, userIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationUsers.GetByIDs", err, - "org_id", orgResp.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationUsers.GetByIDs: org_id=%s: %w", orgResp.ID, err)) } var rolePairPBs []*frontierv1beta1.ListOrganizationUsersResponse_RolePair @@ -420,8 +365,7 @@ func (h *ConnectHandler) ListOrganizationUsers(ctx context.Context, request *con for _, rel := range users { u, err := transformUserToPB(rel) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationUsers", rel.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationUsers: entity_id=%s: %w", rel.ID, err)) } usersPB = append(usersPB, u) } @@ -433,8 +377,6 @@ func (h *ConnectHandler) ListOrganizationUsers(ctx context.Context, request *con } func (h *ConnectHandler) RemoveOrganizationMember(ctx context.Context, request *connect.Request[frontierv1beta1.RemoveOrganizationMemberRequest]) (*connect.Response[frontierv1beta1.RemoveOrganizationMemberResponse], error) { - errorLogger := NewErrorLogger() - orgID := request.Msg.GetOrgId() principalID := request.Msg.GetPrincipalId() principalType := request.Msg.GetPrincipalType() @@ -458,11 +400,7 @@ func (h *ConnectHandler) RemoveOrganizationMember(ctx context.Context, request * case errors.Is(err, membership.ErrLastOwnerRole): return nil, connect.NewError(connect.CodeFailedPrecondition, membership.ErrLastOwnerRole) default: - errorLogger.LogServiceError(ctx, request, "RemoveOrganizationMember", err, - "org_id", orgID, - "principal_id", principalID, - "principal_type", principalType) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RemoveOrganizationMember: org_id=%s principal_id=%s principal_type=%s: %w", orgID, principalID, principalType, err)) } } @@ -500,7 +438,7 @@ func (h *ConnectHandler) SetOrganizationMemberRole(ctx context.Context, request case errors.Is(err, membership.ErrLastOwnerRole): return nil, connect.NewError(connect.CodeFailedPrecondition, ErrLastOwnerRole) default: - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, err) } } @@ -568,30 +506,20 @@ func toClientError(err error) string { } func (h *ConnectHandler) EnableOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.EnableOrganizationRequest]) (*connect.Response[frontierv1beta1.EnableOrganizationResponse], error) { - errorLogger := NewErrorLogger() - if err := h.orgService.Enable(ctx, request.Msg.GetId()); err != nil { - errorLogger.LogServiceError(ctx, request, "EnableOrganization.Enable", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableOrganization.Enable: org_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.EnableOrganizationResponse{}), nil } func (h *ConnectHandler) DisableOrganization(ctx context.Context, request *connect.Request[frontierv1beta1.DisableOrganizationRequest]) (*connect.Response[frontierv1beta1.DisableOrganizationResponse], error) { - errorLogger := NewErrorLogger() - if err := h.orgService.Disable(ctx, request.Msg.GetId()); err != nil { - errorLogger.LogServiceError(ctx, request, "DisableOrganization.Disable", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DisableOrganization.Disable: org_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.DisableOrganizationResponse{}), nil } func (h *ConnectHandler) ListOrganizationServiceUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationServiceUsersRequest]) (*connect.Response[frontierv1beta1.ListOrganizationServiceUsersResponse], error) { - errorLogger := NewErrorLogger() - orgResp, err := h.orgService.Get(ctx, request.Msg.GetId()) if err != nil { switch { @@ -600,9 +528,7 @@ func (h *ConnectHandler) ListOrganizationServiceUsers(ctx context.Context, reque case errors.Is(err, organization.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogServiceError(ctx, request, "ListOrganizationServiceUsers.Get", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationServiceUsers.Get: org_id=%s: %w", request.Msg.GetId(), err)) } } @@ -610,17 +536,14 @@ func (h *ConnectHandler) ListOrganizationServiceUsers(ctx context.Context, reque OrgID: orgResp.ID, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationServiceUsers.List", err, - "org_id", orgResp.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationServiceUsers.List: org_id=%s: %w", orgResp.ID, err)) } var usersPB []*frontierv1beta1.ServiceUser for _, rel := range usersList { u, err := transformServiceUserToPB(rel) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationServiceUsers", rel.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationServiceUsers: entity_id=%s: %w", rel.ID, err)) } usersPB = append(usersPB, u) diff --git a/internal/api/v1beta1connect/organization_billing.go b/internal/api/v1beta1connect/organization_billing.go index 1d895a652..06a4c7b96 100644 --- a/internal/api/v1beta1connect/organization_billing.go +++ b/internal/api/v1beta1connect/organization_billing.go @@ -14,8 +14,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizations(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationsRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationsResponse], error) { - errorLogger := NewErrorLogger() - var orgs []*frontierv1beta1.SearchOrganizationsResponse_OrganizationResult rqlQuery, err := transformProtoToRQL(request.Msg.GetQuery()) @@ -30,8 +28,7 @@ func (h *ConnectHandler) SearchOrganizations(ctx context.Context, request *conne orgBillingData, err := h.orgBillingService.Search(ctx, rqlQuery) if err != nil { - errorLogger.LogServiceError(ctx, request, "SearchOrganizations.Search", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizations.Search: %w", err)) } for _, v := range orgBillingData.Organizations { @@ -59,15 +56,12 @@ func (h *ConnectHandler) SearchOrganizations(ctx context.Context, request *conne } func (h *ConnectHandler) ExportOrganizations(ctx context.Context, request *connect.Request[frontierv1beta1.ExportOrganizationsRequest], stream *connect.ServerStream[httpbody.HttpBody]) error { - errorLogger := NewErrorLogger() - orgBillingDataBytes, contentType, err := h.orgBillingService.Export(ctx) if err != nil { if errors.Is(err, orgbilling.ErrNoContent) { return connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("no data to export: %v", err)) } - errorLogger.LogServiceError(ctx, request, "ExportOrganizations.Export", err) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("ExportOrganizations.Export: %w", err)) } return streamBytesInChunks(orgBillingDataBytes, contentType, stream) } diff --git a/internal/api/v1beta1connect/organization_invoices.go b/internal/api/v1beta1connect/organization_invoices.go index 0d1d39abd..800a5de5d 100644 --- a/internal/api/v1beta1connect/organization_invoices.go +++ b/internal/api/v1beta1connect/organization_invoices.go @@ -15,8 +15,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizationInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationInvoicesRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationInvoicesResponse], error) { - errorLogger := NewErrorLogger() - var orgInvoices []*frontierv1beta1.SearchOrganizationInvoicesResponse_OrganizationInvoice rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), orginvoices.AggregatedInvoice{}) @@ -34,9 +32,7 @@ func (h *ConnectHandler) SearchOrganizationInvoices(ctx context.Context, request if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrInternalServerError) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationInvoices.Search", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationInvoices.Search: org_id=%s: %w", request.Msg.GetId(), err)) } for _, v := range invoicesData.Invoices { diff --git a/internal/api/v1beta1connect/organization_pats.go b/internal/api/v1beta1connect/organization_pats.go index 451b5c816..af4ee13da 100644 --- a/internal/api/v1beta1connect/organization_pats.go +++ b/internal/api/v1beta1connect/organization_pats.go @@ -22,8 +22,6 @@ const orgPATsDefaultLimit = 30 const orgPATsMaxLimit = 30 func (h *ConnectHandler) SearchOrganizationPATs(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationPATsRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationPATsResponse], error) { - errorLogger := NewErrorLogger() - rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), svc.PATSearchFields{}) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("failed to read rql query: %v", err)) @@ -46,9 +44,7 @@ func (h *ConnectHandler) SearchOrganizationPATs(ctx context.Context, request *co if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationPATs.Search", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationPATs.Search: org_id=%s: %w", request.Msg.GetOrgId(), err)) } orgPATs := make([]*frontierv1beta1.SearchOrganizationPATsResponse_OrganizationPAT, 0, len(result.PATs)) diff --git a/internal/api/v1beta1connect/organization_pats_test.go b/internal/api/v1beta1connect/organization_pats_test.go index b5d8a25ba..bd348b16a 100644 --- a/internal/api/v1beta1connect/organization_pats_test.go +++ b/internal/api/v1beta1connect/organization_pats_test.go @@ -38,7 +38,7 @@ func TestHandler_SearchOrganizationPATs(t *testing.T) { request: connect.NewRequest(&frontierv1beta1.SearchOrganizationPATsRequest{ OrgId: testOrgID, }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("db error")), }, { name: "should return invalid argument on bad input error", diff --git a/internal/api/v1beta1connect/organization_projects.go b/internal/api/v1beta1connect/organization_projects.go index 38460cd97..d2397896d 100644 --- a/internal/api/v1beta1connect/organization_projects.go +++ b/internal/api/v1beta1connect/organization_projects.go @@ -16,8 +16,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizationProjects(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationProjectsRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationProjectsResponse], error) { - errorLogger := NewErrorLogger() - var orgProjects []*frontierv1beta1.SearchOrganizationProjectsResponse_OrganizationProject rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), orgprojects.AggregatedProject{}) @@ -35,9 +33,7 @@ func (h *ConnectHandler) SearchOrganizationProjects(ctx context.Context, request if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrInternalServerError) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationProjects.Search", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationProjects.Search: org_id=%s: %w", request.Msg.GetId(), err)) } for _, v := range orgProjectsData.Projects { @@ -80,16 +76,12 @@ func transformAggregatedProjectToPB(p orgprojects.AggregatedProject) *frontierv1 } func (h *ConnectHandler) ExportOrganizationProjects(ctx context.Context, request *connect.Request[frontierv1beta1.ExportOrganizationProjectsRequest], stream *connect.ServerStream[httpbody.HttpBody]) error { - errorLogger := NewErrorLogger() - orgProjectsDataBytes, contentType, err := h.orgProjectsService.Export(ctx, request.Msg.GetId()) if err != nil { if errors.Is(err, orgprojects.ErrNoContent) { return connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("no data to export: %v", err)) } - errorLogger.LogServiceError(ctx, request, "ExportOrganizationProjects.Export", err, - "org_id", request.Msg.GetId()) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("ExportOrganizationProjects.Export: org_id=%s: %w", request.Msg.GetId(), err)) } return streamBytesInChunks(orgProjectsDataBytes, contentType, stream) diff --git a/internal/api/v1beta1connect/organization_serviceuser.go b/internal/api/v1beta1connect/organization_serviceuser.go index ccb7ee209..1546ec521 100644 --- a/internal/api/v1beta1connect/organization_serviceuser.go +++ b/internal/api/v1beta1connect/organization_serviceuser.go @@ -14,8 +14,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizationServiceUsers(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationServiceUsersRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationServiceUsersResponse], error) { - errorLogger := NewErrorLogger() - rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), orgserviceuser.AggregatedServiceUser{}) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("failed to read rql query: %v", err)) @@ -26,9 +24,7 @@ func (h *ConnectHandler) SearchOrganizationServiceUsers(ctx context.Context, req if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationServiceUsers.Search", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationServiceUsers.Search: org_id=%s: %w", request.Msg.GetId(), err)) } var orgServiceUsers []*frontierv1beta1.SearchOrganizationServiceUsersResponse_OrganizationServiceUser diff --git a/internal/api/v1beta1connect/organization_serviceuser_credentials.go b/internal/api/v1beta1connect/organization_serviceuser_credentials.go index 1f98536d0..bcdf9adfe 100644 --- a/internal/api/v1beta1connect/organization_serviceuser_credentials.go +++ b/internal/api/v1beta1connect/organization_serviceuser_credentials.go @@ -15,8 +15,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizationServiceUserCredentials(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationServiceUserCredentialsRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationServiceUserCredentialsResponse], error) { - errorLogger := NewErrorLogger() - rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), svc.AggregatedServiceUserCredential{}) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("failed to read rql query: %v", err)) @@ -32,9 +30,7 @@ func (h *ConnectHandler) SearchOrganizationServiceUserCredentials(ctx context.Co if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationServiceUserCredentials.Search", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationServiceUserCredentials.Search: org_id=%s: %w", request.Msg.GetId(), err)) } var orgCredentials []*frontierv1beta1.SearchOrganizationServiceUserCredentialsResponse_OrganizationServiceUserCredential diff --git a/internal/api/v1beta1connect/organization_test.go b/internal/api/v1beta1connect/organization_test.go index b36ee9be4..126306137 100644 --- a/internal/api/v1beta1connect/organization_test.go +++ b/internal/api/v1beta1connect/organization_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -63,7 +64,7 @@ func TestHandler_ListOrganizations(t *testing.T) { }, request: connect.NewRequest(&frontierv1beta1.ListOrganizationsRequest{}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizations.List: state=%s user_id=%s: %w", "", "", errors.New("test error"))), }, { name: "should return success if org service return nil", @@ -164,7 +165,7 @@ func TestHandler_CreateOrganization(t *testing.T) { Metadata: &structpb.Struct{}, }}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganization.Create: org_name=%s org_title=%s: %w", "abc", "", errors.New("test error"))), }, { name: "should return invalid argument error if name is empty", @@ -320,7 +321,7 @@ func TestHandler_UpdateOrganization(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateOrganization.Update: org_id=%s org_name=%s org_title=%s: %w", someOrgID, "new-org", "", errors.New("test error"))), }, { name: "should return not found error if org id is not uuid (slug) and not exist", @@ -574,7 +575,7 @@ func TestHandler_ListOrganizationProjects(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationProjects.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return internal error if project service return some error", @@ -589,7 +590,7 @@ func TestHandler_ListOrganizationProjects(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationProjects.List: org_id=%s with_member_count=%v: %w", testOrgID, false, errors.New("test error"))), }, { name: "should return list of projects successfully", @@ -729,7 +730,7 @@ func TestHandler_ListOrganizationAdmins(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins.ListPrincipalsByResource: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return error if org id does not exist", @@ -762,7 +763,7 @@ func TestHandler_ListOrganizationAdmins(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationAdmins.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return success if org service return nil error", @@ -849,7 +850,7 @@ func TestHandler_ListOrganizationUsers(t *testing.T) { Id: "some-org-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationUsers.Get: org_id=%s: %w", "some-org-id", errors.New("test error"))), }, { name: "should return not found error if org id does not exist", @@ -885,7 +886,7 @@ func TestHandler_ListOrganizationUsers(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationUsers.ListPrincipalsByResource: org_id=%s role_ids=%v: %w", testOrgID, ([]string)(nil), errors.New("test error"))), }, { name: "should return success if org service return nil error", @@ -1028,7 +1029,7 @@ func TestHandler_RemoveOrganizationMember(t *testing.T) { PrincipalType: schema.UserPrincipal, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("RemoveOrganizationMember: org_id=%s principal_id=%s principal_type=%s: %w", testOrgID, "some-user-id", schema.UserPrincipal, errors.New("unexpected"))), }, { name: "should remove member successfully", @@ -1078,7 +1079,7 @@ func TestHandler_EnableOrganization(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("EnableOrganization.Enable: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should enable org successfully", @@ -1123,7 +1124,7 @@ func TestHandler_DisableOrganization(t *testing.T) { Id: "some-org-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DisableOrganization.Disable: org_id=%s: %w", "some-org-id", errors.New("test error"))), }, { name: "should disable org successfully", @@ -1168,7 +1169,7 @@ func TestHandler_ListOrganizationServiceUsers(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationServiceUsers.Get: org_id=%s: %w", testOrgID, errors.New("test error"))), }, { name: "should return org not found error if org doesnt exist", @@ -1204,7 +1205,7 @@ func TestHandler_ListOrganizationServiceUsers(t *testing.T) { Id: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationServiceUsers.List: org_id=%s: %w", testOrgID, errors.New("service user error"))), }, { name: "should return success if org service return nil error", @@ -1385,7 +1386,7 @@ func TestHandler_SetOrganizationMemberRole(t *testing.T) { RoleId: "9f256f86-31a3-11ec-8d3d-0242ac130005", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, errors.New("unknown error")), }, { name: "should return success on valid request", diff --git a/internal/api/v1beta1connect/organization_tokens.go b/internal/api/v1beta1connect/organization_tokens.go index 62caf328f..72949bcc2 100644 --- a/internal/api/v1beta1connect/organization_tokens.go +++ b/internal/api/v1beta1connect/organization_tokens.go @@ -16,8 +16,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizationTokens(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationTokensRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationTokensResponse], error) { - errorLogger := NewErrorLogger() - rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), svc.AggregatedToken{}) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("failed to read rql query: %v", err)) @@ -33,9 +31,7 @@ func (h *ConnectHandler) SearchOrganizationTokens(ctx context.Context, request * if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationTokens.Search", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationTokens.Search: org_id=%s: %w", request.Msg.GetId(), err)) } var orgTokens []*frontierv1beta1.SearchOrganizationTokensResponse_OrganizationToken @@ -68,16 +64,12 @@ func transformAggregatedTokenToPB(v svc.AggregatedToken) *frontierv1beta1.Search } func (h *ConnectHandler) ExportOrganizationTokens(ctx context.Context, request *connect.Request[frontierv1beta1.ExportOrganizationTokensRequest], stream *connect.ServerStream[httpbody.HttpBody]) error { - errorLogger := NewErrorLogger() - orgTokensDataBytes, contentType, err := h.orgTokensService.Export(ctx, request.Msg.GetId()) if err != nil { if errors.Is(err, svc.ErrNoContent) { return connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("no data to export: %v", err)) } - errorLogger.LogServiceError(ctx, request, "ExportOrganizationTokens.Export", err, - "org_id", request.Msg.GetId()) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("ExportOrganizationTokens.Export: org_id=%s: %w", request.Msg.GetId(), err)) } return streamBytesInChunks(orgTokensDataBytes, contentType, stream) diff --git a/internal/api/v1beta1connect/organization_users.go b/internal/api/v1beta1connect/organization_users.go index 7c7670f44..cf8930753 100644 --- a/internal/api/v1beta1connect/organization_users.go +++ b/internal/api/v1beta1connect/organization_users.go @@ -16,8 +16,6 @@ import ( ) func (h *ConnectHandler) SearchOrganizationUsers(ctx context.Context, request *connect.Request[frontierv1beta1.SearchOrganizationUsersRequest]) (*connect.Response[frontierv1beta1.SearchOrganizationUsersResponse], error) { - errorLogger := NewErrorLogger() - var orgUsers []*frontierv1beta1.SearchOrganizationUsersResponse_OrganizationUser rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), orgusers.AggregatedUser{}) @@ -39,9 +37,7 @@ func (h *ConnectHandler) SearchOrganizationUsers(ctx context.Context, request *c if errors.Is(err, postgres.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "SearchOrganizationUsers.Search", err, - "org_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchOrganizationUsers.Search: org_id=%s: %w", request.Msg.GetId(), err)) } for _, v := range orgUsersData.Users { @@ -85,16 +81,12 @@ func transformAggregatedUserToPB(v orgusers.AggregatedUser) *frontierv1beta1.Sea } func (h *ConnectHandler) ExportOrganizationUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ExportOrganizationUsersRequest], stream *connect.ServerStream[httpbody.HttpBody]) error { - errorLogger := NewErrorLogger() - orgUsersDataBytes, contentType, err := h.orgUsersService.Export(ctx, request.Msg.GetId()) if err != nil { if errors.Is(err, orgusers.ErrNoContent) { return connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("no data to export: %v", err)) } - errorLogger.LogServiceError(ctx, request, "ExportOrganizationUsers.Export", err, - "org_id", request.Msg.GetId()) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("ExportOrganizationUsers.Export: org_id=%s: %w", request.Msg.GetId(), err)) } return streamBytesInChunks(orgUsersDataBytes, contentType, stream) } @@ -111,7 +103,7 @@ func streamBytesInChunks(data []byte, contentType string, stream *connect.Server } if err := stream.Send(msg); err != nil { - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("streamBytesInChunks: %w", err)) } } return nil diff --git a/internal/api/v1beta1connect/permission.go b/internal/api/v1beta1connect/permission.go index c756c1763..cdc902804 100644 --- a/internal/api/v1beta1connect/permission.go +++ b/internal/api/v1beta1connect/permission.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/namespace" @@ -62,25 +63,20 @@ func (h *ConnectHandler) CreatePermission(ctx context.Context, request *connect. errors.Is(err, permission.ErrInvalidID): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreatePermission.AppendSchema", err, - "permission_slugs", permissionSlugs) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePermission.AppendSchema: permission_slugs=%v: %w", permissionSlugs, err)) } } permList, err := h.permissionService.List(ctx, permission.Filter{Slugs: permissionSlugs}) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreatePermission.List", err, - "permission_slugs", permissionSlugs) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePermission.List: permission_slugs=%v: %w", permissionSlugs, err)) } var pbPerms []*frontierv1beta1.Permission for _, perm := range permList { permPB, err := transformPermissionToPB(perm) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreatePermission", perm.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePermission: entity_id=%s: %w", perm.ID, err)) } pbPerms = append(pbPerms, permPB) } @@ -141,38 +137,29 @@ func (h *ConnectHandler) UpdatePermission(ctx context.Context, request *connect. errors.Is(err, permission.ErrInvalidDetail): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdatePermission", err, - "permission_id", request.Msg.GetId(), - "permission_name", permName, - "permission_namespace", permNamespace) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdatePermission: permission_id=%s permission_name=%s permission_namespace=%s: %w", request.Msg.GetId(), permName, permNamespace, err)) } } permissionPB, err := transformPermissionToPB(updatedPermission) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdatePermission", updatedPermission.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdatePermission: entity_id=%s: %w", updatedPermission.ID, err)) } return connect.NewResponse(&frontierv1beta1.UpdatePermissionResponse{Permission: permissionPB}), nil } func (h *ConnectHandler) ListPermissions(ctx context.Context, request *connect.Request[frontierv1beta1.ListPermissionsRequest]) (*connect.Response[frontierv1beta1.ListPermissionsResponse], error) { - errorLogger := NewErrorLogger() - actionsList, err := h.permissionService.List(ctx, permission.Filter{}) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListPermissions", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPermissions: %w", err)) } var perms []*frontierv1beta1.Permission for _, act := range actionsList { actPB, err := transformPermissionToPB(act) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListPermissions", act.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPermissions: entity_id=%s: %w", act.ID, err)) } perms = append(perms, actPB) } @@ -192,16 +179,13 @@ func (h *ConnectHandler) GetPermission(ctx context.Context, request *connect.Req case errors.Is(err, permission.ErrNotExist), errors.Is(err, permission.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetPermission", err, - "permission_id", permissionID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetPermission: permission_id=%s: %w", permissionID, err)) } } permissionPB, err := transformPermissionToPB(fetchedPermission) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetPermission", fetchedPermission.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetPermission: entity_id=%s: %w", fetchedPermission.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetPermissionResponse{Permission: permissionPB}), nil diff --git a/internal/api/v1beta1connect/permission_check.go b/internal/api/v1beta1connect/permission_check.go index 3af7e923b..3fc2ea8d1 100644 --- a/internal/api/v1beta1connect/permission_check.go +++ b/internal/api/v1beta1connect/permission_check.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/audit" @@ -30,7 +31,7 @@ func logAuditForCheck(ctx context.Context, result bool, objectID string, objectN func (h *ConnectHandler) getPermissionName(ctx context.Context, ns, name string) (string, error) { resolved, ok, err := h.resolvePermissionName(ctx, ns, name) if err != nil { - return "", connect.NewError(connect.CodeInternal, ErrInternalServerError) + return "", connect.NewError(connect.CodeInternal, fmt.Errorf("getPermissionName: %w", err)) } if !ok { return "", connect.NewError(connect.CodeNotFound, ErrNotFound) @@ -114,7 +115,7 @@ func (h *ConnectHandler) fetchAccessPairsOnResource(ctx context.Context, objectN for _, p := range permissions { resolved, ok, err := h.resolvePermissionName(ctx, objectNamespace, p) if err != nil { - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("fetchAccessPairsOnResource: %w", err)) } if !ok { continue @@ -143,7 +144,7 @@ func (h *ConnectHandler) fetchAccessPairsOnResource(ctx context.Context, objectN } checkPairs, err := h.resourceService.BatchCheck(ctx, checks) if err != nil { - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("fetchAccessPairsOnResource: %w", err)) } // remove all the failed checks return utils.Filter(checkPairs, func(pair relation.CheckPair) bool { @@ -190,8 +191,6 @@ func (h *ConnectHandler) CheckResourcePermission(ctx context.Context, req *conne } func (h *ConnectHandler) BatchCheckPermission(ctx context.Context, req *connect.Request[frontierv1beta1.BatchCheckPermissionRequest]) (*connect.Response[frontierv1beta1.BatchCheckPermissionResponse], error) { - errorLogger := NewErrorLogger() - checks := make([]resource.Check, 0, len(req.Msg.GetBodies())) for _, body := range req.Msg.GetBodies() { objectNamespace, objectID, err := schema.SplitNamespaceAndResourceID(body.GetResource()) @@ -213,9 +212,7 @@ func (h *ConnectHandler) BatchCheckPermission(ctx context.Context, req *connect. } result, err := h.resourceService.BatchCheck(ctx, checks) if err != nil { - errorLogger.LogServiceError(ctx, req, "BatchCheckPermission", err, - "batch_size", len(checks)) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("BatchCheckPermission: batch_size=%d: %w", len(checks), err)) } pairs := make([]*frontierv1beta1.BatchCheckPermissionResponsePair, 0, len(result)) diff --git a/internal/api/v1beta1connect/permission_check_test.go b/internal/api/v1beta1connect/permission_check_test.go index 740100cd5..7cc281a2b 100644 --- a/internal/api/v1beta1connect/permission_check_test.go +++ b/internal/api/v1beta1connect/permission_check_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "connectrpc.com/connect" @@ -75,7 +76,7 @@ func TestHandler_CheckResourcePermission(t *testing.T) { Resource: schema.JoinNamespaceAndResourceID(testRelationV2.Object.Namespace, testRelationV2.Object.ID), }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("handleAuthErr: %w", errors.New("test error"))), }, { name: "should return true when CheckAuthz function returns true bool", diff --git a/internal/api/v1beta1connect/permission_test.go b/internal/api/v1beta1connect/permission_test.go index 75cecaf69..b327cb4d8 100644 --- a/internal/api/v1beta1connect/permission_test.go +++ b/internal/api/v1beta1connect/permission_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "time" @@ -75,8 +76,10 @@ func TestHandler_CreatePermission(t *testing.T) { }, }, }), - want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + want: nil, + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePermission.AppendSchema: permission_slugs=%v: %w", + []string{schema.FQPermissionNameFromNamespace(testPermissions[testPermissionIdx].NamespaceID, testPermissions[testPermissionIdx].Name)}, + errors.New("test error"))), }, { name: "should return bad request error if namespace id is empty", @@ -256,8 +259,10 @@ func TestHandler_UpdatePermission(t *testing.T) { Namespace: testPermissions[testPermissionIdx].NamespaceID, }, }), - want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + want: nil, + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("UpdatePermission: permission_id=%s permission_name=%s permission_namespace=%s: %w", + testPermissions[testPermissionIdx].ID, testPermissions[testPermissionIdx].Name, testPermissions[testPermissionIdx].NamespaceID, + errors.New("test error"))), }, { name: "should return not found error if permission id not exist", @@ -386,7 +391,7 @@ func TestHandler_ListPermissions(t *testing.T) { }, request: connect.NewRequest(&frontierv1beta1.ListPermissionsRequest{}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListPermissions: %w", errors.New("test error"))), }, { name: "should return success if permission service return nil error", @@ -461,7 +466,7 @@ func TestHandler_GetPermission(t *testing.T) { Id: testPermissions[testPermissionIdx].ID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetPermission: permission_id=%s: %w", testPermissions[testPermissionIdx].ID, errors.New("test error"))), }, { name: "should return not found error if permission id not exist", diff --git a/internal/api/v1beta1connect/platform.go b/internal/api/v1beta1connect/platform.go index 55e4113d3..4289d5cce 100644 --- a/internal/api/v1beta1connect/platform.go +++ b/internal/api/v1beta1connect/platform.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/relation" @@ -11,7 +12,6 @@ import ( ) func (h *ConnectHandler) AddPlatformUser(ctx context.Context, req *connect.Request[frontierv1beta1.AddPlatformUserRequest]) (*connect.Response[frontierv1beta1.AddPlatformUserResponse], error) { - errorLogger := NewErrorLogger() relationName := req.Msg.GetRelation() if !schema.IsPlatformRelation(relationName) { @@ -20,17 +20,11 @@ func (h *ConnectHandler) AddPlatformUser(ctx context.Context, req *connect.Reque if req.Msg.GetUserId() != "" { if err := h.userService.Sudo(ctx, req.Msg.GetUserId(), relationName); err != nil { - errorLogger.LogServiceError(ctx, req, "AddPlatformUser.UserSudo", err, - "user_id", req.Msg.GetUserId(), - "relation", relationName) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AddPlatformUser.UserSudo: user_id=%s relation=%s: %w", req.Msg.GetUserId(), relationName, err)) } } else if req.Msg.GetServiceuserId() != "" { if err := h.serviceUserService.Sudo(ctx, req.Msg.GetServiceuserId(), relationName); err != nil { - errorLogger.LogServiceError(ctx, req, "AddPlatformUser.ServiceUserSudo", err, - "service_user_id", req.Msg.GetServiceuserId(), - "relation", relationName) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("AddPlatformUser.ServiceUserSudo: service_user_id=%s relation=%s: %w", req.Msg.GetServiceuserId(), relationName, err)) } } else { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) @@ -39,19 +33,13 @@ func (h *ConnectHandler) AddPlatformUser(ctx context.Context, req *connect.Reque } func (h *ConnectHandler) RemovePlatformUser(ctx context.Context, req *connect.Request[frontierv1beta1.RemovePlatformUserRequest]) (*connect.Response[frontierv1beta1.RemovePlatformUserResponse], error) { - errorLogger := NewErrorLogger() - if req.Msg.GetUserId() != "" { if err := h.userService.UnSudo(ctx, req.Msg.GetUserId()); err != nil { - errorLogger.LogServiceError(ctx, req, "RemovePlatformUser.UserUnSudo", err, - "user_id", req.Msg.GetUserId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RemovePlatformUser.UserUnSudo: user_id=%s: %w", req.Msg.GetUserId(), err)) } } else if req.Msg.GetServiceuserId() != "" { if err := h.serviceUserService.UnSudo(ctx, req.Msg.GetServiceuserId()); err != nil { - errorLogger.LogServiceError(ctx, req, "RemovePlatformUser.ServiceUserUnSudo", err, - "service_user_id", req.Msg.GetServiceuserId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RemovePlatformUser.ServiceUserUnSudo: service_user_id=%s: %w", req.Msg.GetServiceuserId(), err)) } } else { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) @@ -60,7 +48,6 @@ func (h *ConnectHandler) RemovePlatformUser(ctx context.Context, req *connect.Re } func (h *ConnectHandler) ListPlatformUsers(ctx context.Context, req *connect.Request[frontierv1beta1.ListPlatformUsersRequest]) (*connect.Response[frontierv1beta1.ListPlatformUsersResponse], error) { - errorLogger := NewErrorLogger() relations, err := h.relationService.List(ctx, relation.Filter{ Object: relation.Object{ ID: schema.PlatformID, @@ -68,8 +55,7 @@ func (h *ConnectHandler) ListPlatformUsers(ctx context.Context, req *connect.Req }, }) if err != nil { - errorLogger.LogServiceError(ctx, req, "ListPlatformUsers.ListRelations", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlatformUsers.ListRelations: %w", err)) } subjectRelationMap := make(map[string]string) @@ -85,9 +71,7 @@ func (h *ConnectHandler) ListPlatformUsers(ctx context.Context, req *connect.Req if len(userIDs) > 0 { users, err := h.userService.GetByIDs(ctx, userIDs) if err != nil { - errorLogger.LogServiceError(ctx, req, "ListPlatformUsers.GetUsersByIDs", err, - "user_ids", userIDs) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlatformUsers.GetUsersByIDs: user_ids=%v: %w", userIDs, err)) } for _, u := range users { if u.Metadata == nil { @@ -96,8 +80,7 @@ func (h *ConnectHandler) ListPlatformUsers(ctx context.Context, req *connect.Req u.Metadata["relation"] = subjectRelationMap[u.ID] userPB, err := transformUserToPB(u) if err != nil { - errorLogger.LogTransformError(ctx, req, "ListPlatformUsers.TransformUser", u.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlatformUsers.TransformUser: entity_id=%s: %w", u.ID, err)) } userPBs = append(userPBs, userPB) } @@ -114,9 +97,7 @@ func (h *ConnectHandler) ListPlatformUsers(ctx context.Context, req *connect.Req if len(serviceUserIDs) > 0 { serviceUsers, err := h.serviceUserService.GetByIDs(ctx, serviceUserIDs) if err != nil { - errorLogger.LogServiceError(ctx, req, "ListPlatformUsers.GetServiceUsersByIDs", err, - "service_user_ids", serviceUserIDs) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlatformUsers.GetServiceUsersByIDs: service_user_ids=%v: %w", serviceUserIDs, err)) } for _, u := range serviceUsers { if u.Metadata == nil { @@ -125,8 +106,7 @@ func (h *ConnectHandler) ListPlatformUsers(ctx context.Context, req *connect.Req u.Metadata["relation"] = subjectRelationMap[u.ID] serviceUserPB, err := transformServiceUserToPB(u) if err != nil { - errorLogger.LogTransformError(ctx, req, "ListPlatformUsers.TransformServiceUser", u.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPlatformUsers.TransformServiceUser: entity_id=%s: %w", u.ID, err)) } serviceUserPBs = append(serviceUserPBs, serviceUserPB) } diff --git a/internal/api/v1beta1connect/policy.go b/internal/api/v1beta1connect/policy.go index cb08bdc7d..7dd6e551d 100644 --- a/internal/api/v1beta1connect/policy.go +++ b/internal/api/v1beta1connect/policy.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/audit" @@ -56,20 +57,13 @@ func (h *ConnectHandler) CreatePolicy(ctx context.Context, request *connect.Requ case errors.Is(err, policy.ErrInvalidDetail): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreatePolicy", err, - "role_id", request.Msg.GetBody().GetRoleId(), - "resource_type", resourceType, - "resource_id", resourceID, - "principal_type", principalType, - "principal_id", principalID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePolicy: role_id=%s resource_type=%s resource_id=%s principal_type=%s principal_id=%s: %w", request.Msg.GetBody().GetRoleId(), resourceType, resourceID, principalType, principalID, err)) } } policyPB, err := transformPolicyToPB(newPolicy) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreatePolicy", newPolicy.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePolicy: entity_id=%s: %w", newPolicy.ID, err)) } auditPolicyCreationEvent(ctx, newPolicy) @@ -91,16 +85,13 @@ func (h *ConnectHandler) GetPolicy(ctx context.Context, request *connect.Request errors.Is(err, policy.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrPolicyNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetPolicy", err, - "policy_id", policyID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetPolicy: policy_id=%s: %w", policyID, err)) } } policyPB, err := transformPolicyToPB(fetchedPolicy) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetPolicy", fetchedPolicy.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetPolicy: entity_id=%s: %w", fetchedPolicy.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetPolicyResponse{Policy: policyPB}), nil @@ -126,9 +117,7 @@ func (h *ConnectHandler) DeletePolicy(ctx context.Context, request *connect.Requ case errors.Is(err, policy.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "DeletePolicy", err, - "policy_id", policyID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeletePolicy: policy_id=%s: %w", policyID, err)) } } @@ -180,12 +169,7 @@ func (h *ConnectHandler) CreatePolicyForProject(ctx context.Context, request *co case errors.Is(err, policy.ErrInvalidDetail): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreatePolicyForProject.CreatePolicy", err, - "role_id", request.Msg.GetBody().GetRoleId(), - "project_id", request.Msg.GetProjectId(), - "principal_type", principalType, - "principal_id", principalID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreatePolicyForProject.CreatePolicy: role_id=%s project_id=%s principal_type=%s principal_id=%s: %w", request.Msg.GetBody().GetRoleId(), request.Msg.GetProjectId(), principalType, principalID, err)) } } @@ -210,20 +194,13 @@ func (h *ConnectHandler) ListPolicies(ctx context.Context, request *connect.Requ policyList, err := h.policyService.List(ctx, filter) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListPolicies", err, - "org_id", request.Msg.GetOrgId(), - "project_id", request.Msg.GetProjectId(), - "role_id", request.Msg.GetRoleId(), - "user_id", request.Msg.GetUserId(), - "group_id", request.Msg.GetGroupId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPolicies: org_id=%s project_id=%s role_id=%s user_id=%s group_id=%s: %w", request.Msg.GetOrgId(), request.Msg.GetProjectId(), request.Msg.GetRoleId(), request.Msg.GetUserId(), request.Msg.GetGroupId(), err)) } for _, p := range policyList { policyPB, err := transformPolicyToPB(p) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListPolicies", p.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListPolicies: entity_id=%s: %w", p.ID, err)) } policies = append(policies, policyPB) } diff --git a/internal/api/v1beta1connect/preferences.go b/internal/api/v1beta1connect/preferences.go index 357888697..ee06162d4 100644 --- a/internal/api/v1beta1connect/preferences.go +++ b/internal/api/v1beta1connect/preferences.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/preference" @@ -333,6 +334,6 @@ func handlePreferenceError(err error) *connect.Error { case errors.Is(err, preference.ErrInvalidScope): return connect.NewError(connect.CodeInvalidArgument, ErrInvalidPreferenceScope) default: - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("handlePreferenceError: %w", err)) } } diff --git a/internal/api/v1beta1connect/preferences_test.go b/internal/api/v1beta1connect/preferences_test.go index 9dea68986..ed81fa958 100644 --- a/internal/api/v1beta1connect/preferences_test.go +++ b/internal/api/v1beta1connect/preferences_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -217,7 +218,7 @@ func TestConnectHandler_CreateOrganizationPreferences(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("handlePreferenceError: %w", errors.New("database error"))), }, { name: "should create multiple preferences successfully", @@ -360,7 +361,7 @@ func TestConnectHandler_ListOrganizationPreferences(t *testing.T) { Id: "error_org", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("handlePreferenceError: %w", errors.New("database error"))), }, { name: "should list multiple preferences successfully", @@ -494,7 +495,7 @@ func TestConnectHandler_CreateUserPreferences(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("handlePreferenceError: %w", errors.New("database connection failed"))), }, { name: "should create multiple user preferences successfully", @@ -651,7 +652,7 @@ func TestConnectHandler_ListUserPreferences(t *testing.T) { Id: "user_error", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("handlePreferenceError: %w", errors.New("database connection failed"))), }, { name: "should list multiple user preferences successfully", @@ -1026,7 +1027,7 @@ func TestConnectHandler_ListCurrentUserPreferences(t *testing.T) { }).Return(nil, errors.New("database error")) }, want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("handlePreferenceError: %w", errors.New("database error"))), }, { name: "should return multiple preferences for current user", diff --git a/internal/api/v1beta1connect/project.go b/internal/api/v1beta1connect/project.go index e91e4e6b4..eb7048c50 100644 --- a/internal/api/v1beta1connect/project.go +++ b/internal/api/v1beta1connect/project.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/audit" @@ -21,7 +22,6 @@ import ( ) func (h *ConnectHandler) ListProjects(ctx context.Context, request *connect.Request[frontierv1beta1.ListProjectsRequest]) (*connect.Response[frontierv1beta1.ListProjectsResponse], error) { - errorLogger := NewErrorLogger() var projects []*frontierv1beta1.Project projectList, err := h.projectService.List(ctx, project.Filter{ @@ -29,17 +29,13 @@ func (h *ConnectHandler) ListProjects(ctx context.Context, request *connect.Requ OrgID: request.Msg.GetOrgId(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjects", err, - "org_id", request.Msg.GetOrgId(), - "state", request.Msg.GetState()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjects: org_id=%s state=%s: %w", request.Msg.GetOrgId(), request.Msg.GetState(), err)) } for _, v := range projectList { projectPB, err := transformProjectToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjects", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjects: entity_id=%s: %w", v.ID, err)) } projects = append(projects, projectPB) @@ -74,8 +70,7 @@ func (h *ConnectHandler) CreateProject(ctx context.Context, request *connect.Req projectPB, err := transformProjectToPB(newProject) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateProject", newProject.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProject: entity_id=%s: %w", newProject.ID, err)) } auditor.Log(audit.ProjectCreatedEvent, audit.ProjectTarget(newProject.ID)) return connect.NewResponse(&frontierv1beta1.CreateProjectResponse{Project: projectPB}), nil @@ -94,8 +89,7 @@ func (h *ConnectHandler) GetProject(ctx context.Context, request *connect.Reques projectPB, err := transformProjectToPB(fetchedProject) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetProject", fetchedProject.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProject: entity_id=%s: %w", fetchedProject.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetProjectResponse{Project: projectPB}), nil @@ -125,8 +119,7 @@ func (h *ConnectHandler) UpdateProject(ctx context.Context, request *connect.Req projectPB, err := transformProjectToPB(updatedProject) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateProject", updatedProject.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProject: entity_id=%s: %w", updatedProject.ID, err)) } audit.GetAuditor(ctx, updatedProject.Organization.ID).Log(audit.ProjectUpdatedEvent, audit.ProjectTarget(updatedProject.ID)) @@ -146,10 +139,7 @@ func (h *ConnectHandler) ListProjectAdmins(ctx context.Context, request *connect ownerRole, err := h.roleService.Get(ctx, project.OwnerRole) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectAdmins.roleService.Get", err, - "project_id", prj.ID, - "role", project.OwnerRole) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectAdmins.roleService.Get: project_id=%s role=%s: %w", prj.ID, project.OwnerRole, err)) } members, err := h.membershipService.ListPrincipalsByResource(ctx, prj.ID, schema.ProjectNamespace, membership.MemberFilter{ @@ -157,25 +147,20 @@ func (h *ConnectHandler) ListProjectAdmins(ctx context.Context, request *connect RoleIDs: []string{ownerRole.ID}, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectAdmins.ListPrincipalsByResource", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectAdmins.ListPrincipalsByResource: project_id=%s: %w", prj.ID, err)) } userIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) users, err := h.userService.GetByIDs(ctx, userIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectAdmins.GetByIDs", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectAdmins.GetByIDs: project_id=%s: %w", prj.ID, err)) } var transformedAdmins []*frontierv1beta1.User for _, a := range users { u, err := transformUserToPB(a) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectAdmins", a.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectAdmins: entity_id=%s: %w", a.ID, err)) } transformedAdmins = append(transformedAdmins, u) @@ -199,17 +184,13 @@ func (h *ConnectHandler) ListProjectUsers(ctx context.Context, request *connect. PrincipalType: schema.UserPrincipal, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectUsers.ListPrincipalsByResource", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectUsers.ListPrincipalsByResource: project_id=%s: %w", prj.ID, err)) } userIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) users, err := h.userService.GetByIDs(ctx, userIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectUsers.GetByIDs", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectUsers.GetByIDs: project_id=%s: %w", prj.ID, err)) } var transformedUsers []*frontierv1beta1.User @@ -217,8 +198,7 @@ func (h *ConnectHandler) ListProjectUsers(ctx context.Context, request *connect. for _, a := range users { u, err := transformUserToPB(a) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectUsers", a.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectUsers: entity_id=%s: %w", a.ID, err)) } transformedUsers = append(transformedUsers, u) @@ -262,9 +242,7 @@ func (h *ConnectHandler) ListProjectServiceUsers(ctx context.Context, request *c PrincipalType: schema.ServiceUserPrincipal, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectServiceUsers.ListPrincipalsByResource", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectServiceUsers.ListPrincipalsByResource: project_id=%s: %w", prj.ID, err)) } suIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) @@ -272,9 +250,7 @@ func (h *ConnectHandler) ListProjectServiceUsers(ctx context.Context, request *c if len(suIDs) > 0 { users, err = h.serviceUserService.GetByIDs(ctx, suIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectServiceUsers.GetByIDs", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectServiceUsers.GetByIDs: project_id=%s: %w", prj.ID, err)) } } @@ -283,8 +259,7 @@ func (h *ConnectHandler) ListProjectServiceUsers(ctx context.Context, request *c for _, a := range users { u, err := transformServiceUserToPB(a) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectServiceUsers", a.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectServiceUsers: entity_id=%s: %w", a.ID, err)) } transformedUsers = append(transformedUsers, u) @@ -328,9 +303,7 @@ func (h *ConnectHandler) ListProjectGroups(ctx context.Context, request *connect PrincipalType: schema.GroupPrincipal, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectGroups.ListPrincipalsByResource", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectGroups.ListPrincipalsByResource: project_id=%s: %w", prj.ID, err)) } groupIDs := utils.Map(members, func(m membership.Member) string { return m.PrincipalID }) @@ -338,9 +311,7 @@ func (h *ConnectHandler) ListProjectGroups(ctx context.Context, request *connect if len(groupIDs) > 0 { groups, err = h.groupService.GetByIDs(ctx, groupIDs) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectGroups.GetByIDs", err, - "project_id", prj.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectGroups.GetByIDs: project_id=%s: %w", prj.ID, err)) } } @@ -349,8 +320,7 @@ func (h *ConnectHandler) ListProjectGroups(ctx context.Context, request *connect for _, g := range groups { u, err := transformGroupToPB(g) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectGroups", g.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectGroups: entity_id=%s: %w", g.ID, err)) } groupsPB = append(groupsPB, &u) @@ -441,7 +411,7 @@ func (h *ConnectHandler) SetProjectMemberRole(ctx context.Context, request *conn case errors.Is(err, membership.ErrInvalidPrincipalType): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SetProjectMemberRole: %w", err)) } } @@ -474,7 +444,7 @@ func (h *ConnectHandler) RemoveProjectMember(ctx context.Context, request *conne case errors.Is(err, membership.ErrInvalidPrincipalType): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RemoveProjectMember: %w", err)) } } @@ -514,6 +484,6 @@ func translateProjectServiceError(err error) error { case errors.Is(err, project.ErrNotExist), errors.Is(err, project.ErrInvalidUUID), errors.Is(err, project.ErrInvalidID): return connect.NewError(connect.CodeNotFound, ErrNotFound) default: - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("translateProjectServiceError: %w", err)) } } diff --git a/internal/api/v1beta1connect/project_test.go b/internal/api/v1beta1connect/project_test.go index 68c334473..875a96e0c 100644 --- a/internal/api/v1beta1connect/project_test.go +++ b/internal/api/v1beta1connect/project_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -70,7 +71,7 @@ func TestHandler_ListProjects(t *testing.T) { ps.EXPECT().List(mock.AnythingOfType("context.backgroundCtx"), project.Filter{}).Return([]project.Project{}, errors.New("test error")) }, want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjects: org_id=%s state=%s: %w", "", "", errors.New("test error"))), }, { title: "should return success if project return nil error", @@ -177,7 +178,7 @@ func TestHandler_CreateProject(t *testing.T) { }, }, }}), - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("translateProjectServiceError: %w", errors.New("test error"))), }, { title: "should return bad request error if org id is not uuid", @@ -313,7 +314,7 @@ func TestHandler_GetProject(t *testing.T) { setup: func(ps *mocks.ProjectService) { ps.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), someProjectID).Return(project.Project{}, errors.New("test error")) }, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("translateProjectServiceError: %w", errors.New("test error"))), }, { title: "should return not found error if project doesnt exist", @@ -414,7 +415,7 @@ func TestHandler_UpdateProject(t *testing.T) { Body: updateBody, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("translateProjectServiceError: %w", errors.New("test error"))), }, { name: "should translate organization.ErrInvalidUUID to invalid argument", @@ -515,7 +516,7 @@ func TestHandler_ListProjectAdmins(t *testing.T) { }).Return(nil, errors.New("test error")) }, want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectAdmins.ListPrincipalsByResource: project_id=%s: %w", testProjectID, errors.New("test error"))), }, { title: "should return success if project service return nil error", @@ -595,7 +596,7 @@ func TestHandler_EnableProject(t *testing.T) { ps.EXPECT().Enable(mock.AnythingOfType("context.backgroundCtx"), testProjectID).Return(errors.New("test error")) }, want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("translateProjectServiceError: %w", errors.New("test error"))), }, { title: "should return success if project service return nil error", @@ -640,7 +641,7 @@ func TestHandler_DisableProject(t *testing.T) { ps.EXPECT().Disable(mock.AnythingOfType("context.backgroundCtx"), testProjectID).Return(errors.New("test error")) }, want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("translateProjectServiceError: %w", errors.New("test error"))), }, { title: "should return success if project service return nil error", @@ -688,7 +689,7 @@ func TestHandler_ListProjectUsers(t *testing.T) { }).Return(nil, errors.New("test error")) }, want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectUsers.ListPrincipalsByResource: project_id=%s: %w", testProjectID, errors.New("test error"))), }, { title: "should return success if project service return nil error", diff --git a/internal/api/v1beta1connect/project_users.go b/internal/api/v1beta1connect/project_users.go index 2f4c85ec2..7c7558999 100644 --- a/internal/api/v1beta1connect/project_users.go +++ b/internal/api/v1beta1connect/project_users.go @@ -47,9 +47,7 @@ func (h *ConnectHandler) SearchProjectUsers(ctx context.Context, request *connec "project_id", projectID) return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogUnexpectedError(ctx, request, "SearchProjectUsers", err, - "project_id", projectID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchProjectUsers: project_id=%s: %w", projectID, err)) } for _, v := range projectUsersData.Users { diff --git a/internal/api/v1beta1connect/prospect.go b/internal/api/v1beta1connect/prospect.go index e12d4d991..d69a52fae 100644 --- a/internal/api/v1beta1connect/prospect.go +++ b/internal/api/v1beta1connect/prospect.go @@ -51,11 +51,7 @@ func (h *ConnectHandler) CreateProspectPublic(ctx context.Context, request *conn case errors.Is(err, prospect.ErrEmailActivityAlreadyExists): return connect.NewResponse(&frontierv1beta1.CreateProspectPublicResponse{}), nil default: - errorLogger.LogUnexpectedError(ctx, request, "CreateProspectPublic", err, - "email", strings.ToLower(email), - "activity", activity, - "source", request.Msg.GetSource()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProspectPublic: email=%s activity=%s source=%s: %w", strings.ToLower(email), activity, request.Msg.GetSource(), err)) } } return connect.NewResponse(&frontierv1beta1.CreateProspectPublicResponse{}), nil @@ -103,19 +99,13 @@ func (h *ConnectHandler) CreateProspect(ctx context.Context, request *connect.Re case errors.Is(err, prospect.ErrEmailActivityAlreadyExists): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateProspect", err, - "email", strings.ToLower(email), - "activity", activity, - "status", subsStatus, - "source", request.Msg.GetSource()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProspect: email=%s activity=%s status=%s source=%s: %w", strings.ToLower(email), activity, subsStatus, request.Msg.GetSource(), err)) } } transformedProspect, err := transformProspectToPB(newProspect) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateProspect", newProspect.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProspect: entity_id=%s: %w", newProspect.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreateProspectResponse{Prospect: transformedProspect}), nil } @@ -135,8 +125,7 @@ func (h *ConnectHandler) ListProspects(ctx context.Context, request *connect.Req prospects, err := h.prospectService.List(ctx, requestQuery) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProspects", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProspects: %w", err)) } var transformedProspects []*frontierv1beta1.Prospect @@ -192,15 +181,12 @@ func (h *ConnectHandler) GetProspect(ctx context.Context, request *connect.Reque case errors.Is(err, prospect.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrProspectNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetProspect", err, - "prospect_id", prospectId) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProspect: prospect_id=%s: %w", prospectId, err)) } } transformedProspect, err := transformProspectToPB(prspct) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetProspect", prspct.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProspect: entity_id=%s: %w", prspct.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetProspectResponse{Prospect: transformedProspect}), nil } @@ -227,7 +213,7 @@ func (h *ConnectHandler) UpdateProspect(ctx context.Context, request *connect.Re subsStatus := frontierv1beta1.Prospect_Status_name[int32(reqStatus)] // convert using proto methods metaDataMap, err := buildAndValidateMetadata(request.Msg.GetMetadata().AsMap(), h) if err != nil { - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProspect: %w", err)) } updatedProspect, err := h.prospectService.Update(ctx, prospect.Prospect{ ID: prospectId, @@ -254,19 +240,12 @@ func (h *ConnectHandler) UpdateProspect(ctx context.Context, request *connect.Re case errors.Is(err, prospect.ErrEmailActivityAlreadyExists): return nil, connect.NewError(connect.CodeInvalidArgument, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdateProspect", err, - "prospect_id", prospectId, - "email", strings.ToLower(email), - "activity", activity, - "status", subsStatus, - "source", request.Msg.GetSource()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProspect: prospect_id=%s email=%s activity=%s status=%s source=%s: %w", prospectId, strings.ToLower(email), activity, subsStatus, request.Msg.GetSource(), err)) } } transformedProspect, err := transformProspectToPB(updatedProspect) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateProspect", updatedProspect.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProspect: entity_id=%s: %w", updatedProspect.ID, err)) } return connect.NewResponse(&frontierv1beta1.UpdateProspectResponse{Prospect: transformedProspect}), nil } @@ -287,9 +266,7 @@ func (h *ConnectHandler) DeleteProspect(ctx context.Context, request *connect.Re case errors.Is(err, prospect.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrProspectNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteProspect", err, - "prospect_id", prospectId) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProspect: prospect_id=%s: %w", prospectId, err)) } } return connect.NewResponse(&frontierv1beta1.DeleteProspectResponse{}), nil diff --git a/internal/api/v1beta1connect/prospect_test.go b/internal/api/v1beta1connect/prospect_test.go index a189fb1fe..e9dc13d30 100644 --- a/internal/api/v1beta1connect/prospect_test.go +++ b/internal/api/v1beta1connect/prospect_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "time" @@ -46,7 +47,7 @@ func TestHandler_CreateProspectPublic(t *testing.T) { Metadata: nil, }), want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProspectPublic: email=%s activity=%s source=%s: %w", "test@example.com", "newsletter", "", errors.New("some error"))), }, { title: "should return bad schema error if meta schema service gives error", @@ -159,7 +160,7 @@ func TestHandler_CreateProspect(t *testing.T) { Metadata: nil, }), want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProspect: email=%s activity=%s status=%s source=%s: %w", "test@example.com", "newsletter", "STATUS_SUBSCRIBED", "", errors.New("some error"))), }, { title: "should return bad schema error if meta schema service gives error", @@ -284,7 +285,7 @@ func TestHandler_ListProspects(t *testing.T) { }, req: connect.NewRequest(&frontierv1beta1.ListProspectsRequest{}), want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("ListProspects: %w", errors.New("some error"))), }, { title: "should return success if prospect service return nil error", diff --git a/internal/api/v1beta1connect/relation.go b/internal/api/v1beta1connect/relation.go index cb17c3d8b..4d141324b 100644 --- a/internal/api/v1beta1connect/relation.go +++ b/internal/api/v1beta1connect/relation.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/relation" @@ -13,7 +14,6 @@ import ( ) func (h *ConnectHandler) ListRelations(ctx context.Context, request *connect.Request[frontierv1beta1.ListRelationsRequest]) (*connect.Response[frontierv1beta1.ListRelationsResponse], error) { - errorLogger := NewErrorLogger() var err error var subject relation.Subject var object relation.Object @@ -37,17 +37,13 @@ func (h *ConnectHandler) ListRelations(ctx context.Context, request *connect.Req Object: object, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListRelations", err, - "subject", request.Msg.GetSubject(), - "object", request.Msg.GetObject()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListRelations: subject=%s object=%s: %w", request.Msg.GetSubject(), request.Msg.GetObject(), err)) } for _, r := range relationsList { relationPB, err := transformRelationV2ToPB(r) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListRelations", r.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListRelations: entity_id=%s: %w", r.ID, err)) } relations = append(relations, relationPB) @@ -111,19 +107,13 @@ func (h *ConnectHandler) CreateRelation(ctx context.Context, request *connect.Re case errors.Is(err, relation.ErrInvalidDetail): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateRelation", err, - "subject", request.Msg.GetBody().GetSubject(), - "object", request.Msg.GetBody().GetObject(), - "relation", request.Msg.GetBody().GetRelation(), - "subject_sub_relation", request.Msg.GetBody().GetSubjectSubRelation()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateRelation: subject=%s object=%s relation=%s subject_sub_relation=%s: %w", request.Msg.GetBody().GetSubject(), request.Msg.GetBody().GetObject(), request.Msg.GetBody().GetRelation(), request.Msg.GetBody().GetSubjectSubRelation(), err)) } } relationPB, err := transformRelationV2ToPB(newRelation) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateRelation", newRelation.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateRelation: entity_id=%s: %w", newRelation.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreateRelationResponse{ @@ -146,15 +136,12 @@ func (h *ConnectHandler) GetRelation(ctx context.Context, request *connect.Reque errors.Is(err, relation.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetRelation", err, - "relation_id", relationID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetRelation: relation_id=%s: %w", relationID, err)) } } relationPB, err := transformRelationV2ToPB(fetchedRelation) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetRelation", fetchedRelation.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetRelation: entity_id=%s: %w", fetchedRelation.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetRelationResponse{ Relation: relationPB, @@ -196,11 +183,7 @@ func (h *ConnectHandler) DeleteRelation(ctx context.Context, request *connect.Re errors.Is(err, relation.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteRelation", err, - "subject", request.Msg.GetSubject(), - "object", request.Msg.GetObject(), - "relation", request.Msg.GetRelation()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteRelation: subject=%s object=%s relation=%s: %w", request.Msg.GetSubject(), request.Msg.GetObject(), request.Msg.GetRelation(), err)) } } diff --git a/internal/api/v1beta1connect/relation_test.go b/internal/api/v1beta1connect/relation_test.go index c27c49faf..b6fccc770 100644 --- a/internal/api/v1beta1connect/relation_test.go +++ b/internal/api/v1beta1connect/relation_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "connectrpc.com/connect" @@ -52,7 +53,7 @@ func TestHandler_ListRelations(t *testing.T) { rs.EXPECT().List(mock.AnythingOfType("context.backgroundCtx"), relation.Filter{}).Return([]relation.Relation{}, errors.New("test error")) }, want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListRelations: subject= object=: %w", errors.New("test error"))), }, { name: "should return relations if relation service return nil error", @@ -161,7 +162,7 @@ func TestHandler_CreateRelation(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateRelation: subject=app/user:user@raystack.org object=ns2:object-id relation=member subject_sub_relation=: %w", errors.New("test error"))), }, { name: "should return bad request error if field value not exist in foreign reference", @@ -251,7 +252,7 @@ func TestHandler_GetRelation(t *testing.T) { Id: testRelationV2.ID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetRelation: relation_id=%s: %w", testRelationV2.ID, errors.New("test error"))), }, { name: "should return not found error if id is empty", @@ -381,7 +382,7 @@ func TestHandler_DeleteRelation(t *testing.T) { Relation: testRelationV2.Subject.SubRelationName, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteRelation: subject=%s object=%s relation=%s: %w", schema.JoinNamespaceAndResourceID(testRelationV2.Subject.Namespace, testRelationV2.Subject.ID), schema.JoinNamespaceAndResourceID(testRelationV2.Object.Namespace, testRelationV2.Object.ID), testRelationV2.Subject.SubRelationName, errors.New("test error"))), }, { name: "should successfully delete when relation exist", diff --git a/internal/api/v1beta1connect/resource.go b/internal/api/v1beta1connect/resource.go index 64bde56ab..d3de6cab4 100644 --- a/internal/api/v1beta1connect/resource.go +++ b/internal/api/v1beta1connect/resource.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/audit" @@ -16,7 +17,6 @@ import ( ) func (h *ConnectHandler) ListResources(ctx context.Context, request *connect.Request[frontierv1beta1.ListResourcesRequest]) (*connect.Response[frontierv1beta1.ListResourcesResponse], error) { - errorLogger := NewErrorLogger() var resources []*frontierv1beta1.Resource namespaceID := schema.ParseNamespaceAliasIfRequired(request.Msg.GetNamespace()) filters := resource.Filter{ @@ -25,17 +25,13 @@ func (h *ConnectHandler) ListResources(ctx context.Context, request *connect.Req } resourcesList, err := h.resourceService.List(ctx, filters) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListResources", err, - "namespace", request.Msg.GetNamespace(), - "project_id", request.Msg.GetProjectId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListResources: namespace=%s project_id=%s: %w", request.Msg.GetNamespace(), request.Msg.GetProjectId(), err)) } for _, r := range resourcesList { resourcePB, err := transformResourceToPB(r) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListResources", r.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListResources: entity_id=%s: %w", r.ID, err)) } resources = append(resources, resourcePB) } @@ -46,7 +42,6 @@ func (h *ConnectHandler) ListResources(ctx context.Context, request *connect.Req } func (h *ConnectHandler) ListProjectResources(ctx context.Context, request *connect.Request[frontierv1beta1.ListProjectResourcesRequest]) (*connect.Response[frontierv1beta1.ListProjectResourcesResponse], error) { - errorLogger := NewErrorLogger() var resources []*frontierv1beta1.Resource namespaceID := schema.ParseNamespaceAliasIfRequired(request.Msg.GetNamespace()) filters := resource.Filter{ @@ -55,16 +50,12 @@ func (h *ConnectHandler) ListProjectResources(ctx context.Context, request *conn } resourcesList, err := h.resourceService.List(ctx, filters) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListProjectResources", err, - "namespace", request.Msg.GetNamespace(), - "project_id", request.Msg.GetProjectId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectResources: namespace=%s project_id=%s: %w", request.Msg.GetNamespace(), request.Msg.GetProjectId(), err)) } for _, r := range resourcesList { resourcePB, err := transformResourceToPB(r) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectResources", r.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectResources: entity_id=%s: %w", r.ID, err)) } resources = append(resources, resourcePB) } @@ -88,9 +79,7 @@ func (h *ConnectHandler) CreateProjectResource(ctx context.Context, request *con parentProject, err := h.projectService.Get(ctx, request.Msg.GetProjectId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateProjectResource.GetProject", err, - "project_id", request.Msg.GetProjectId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProjectResource.GetProject: project_id=%s: %w", request.Msg.GetProjectId(), err)) } principalType := schema.UserPrincipal @@ -127,20 +116,13 @@ func (h *ConnectHandler) CreateProjectResource(ctx context.Context, request *con case errors.Is(err, resource.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateProjectResource", err, - "resource_id", request.Msg.GetId(), - "project_id", request.Msg.GetProjectId(), - "resource_name", request.Msg.GetBody().GetName(), - "namespace", request.Msg.GetBody().GetNamespace(), - "principal", request.Msg.GetBody().GetPrincipal()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProjectResource: resource_id=%s project_id=%s resource_name=%s namespace=%s principal=%s: %w", request.Msg.GetId(), request.Msg.GetProjectId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetNamespace(), request.Msg.GetBody().GetPrincipal(), err)) } } resourcePB, err := transformResourceToPB(newResource) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateProjectResource", newResource.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProjectResource: entity_id=%s: %w", newResource.ID, err)) } audit.GetAuditor(ctx, parentProject.Organization.ID).Log(audit.ResourceCreatedEvent, audit.Target{ @@ -167,16 +149,13 @@ func (h *ConnectHandler) GetProjectResource(ctx context.Context, request *connec errors.Is(err, resource.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrResourceNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetProjectResource", err, - "resource_id", resourceID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProjectResource: resource_id=%s: %w", resourceID, err)) } } resourcePB, err := transformResourceToPB(fetchedResource) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetProjectResource", fetchedResource.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetProjectResource: entity_id=%s: %w", fetchedResource.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetProjectResourceResponse{ @@ -199,9 +178,7 @@ func (h *ConnectHandler) UpdateProjectResource(ctx context.Context, request *con parentProject, err := h.projectService.Get(ctx, request.Msg.GetProjectId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "UpdateProjectResource.GetProject", err, - "project_id", request.Msg.GetProjectId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProjectResource.GetProject: project_id=%s: %w", request.Msg.GetProjectId(), err)) } principalType := schema.UserPrincipal @@ -239,20 +216,13 @@ func (h *ConnectHandler) UpdateProjectResource(ctx context.Context, request *con case errors.Is(err, resource.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdateProjectResource", err, - "resource_id", request.Msg.GetId(), - "project_id", request.Msg.GetProjectId(), - "resource_name", request.Msg.GetBody().GetName(), - "namespace", request.Msg.GetBody().GetNamespace(), - "principal", request.Msg.GetBody().GetPrincipal()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProjectResource: resource_id=%s project_id=%s resource_name=%s namespace=%s principal=%s: %w", request.Msg.GetId(), request.Msg.GetProjectId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetNamespace(), request.Msg.GetBody().GetPrincipal(), err)) } } resourcePB, err := transformResourceToPB(updatedResource) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateProjectResource", updatedResource.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProjectResource: entity_id=%s: %w", updatedResource.ID, err)) } audit.GetAuditor(ctx, parentProject.Organization.ID).Log(audit.ResourceUpdatedEvent, audit.Target{ @@ -279,27 +249,18 @@ func (h *ConnectHandler) DeleteProjectResource(ctx context.Context, request *con errors.Is(err, resource.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrResourceNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteProjectResource.GetResource", err, - "resource_id", resourceID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProjectResource.GetResource: resource_id=%s: %w", resourceID, err)) } } parentProject, err := h.projectService.Get(ctx, resourceToDel.ProjectID) if err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteProjectResource.GetProject", err, - "resource_id", resourceID, - "project_id", resourceToDel.ProjectID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProjectResource.GetProject: resource_id=%s project_id=%s: %w", resourceID, resourceToDel.ProjectID, err)) } err = h.resourceService.Delete(ctx, resourceToDel.NamespaceID, resourceToDel.ID) if err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteProjectResource", err, - "resource_id", resourceID, - "project_id", resourceToDel.ProjectID, - "namespace", resourceToDel.NamespaceID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProjectResource: resource_id=%s project_id=%s namespace=%s: %w", resourceID, resourceToDel.ProjectID, resourceToDel.NamespaceID, err)) } audit.GetAuditor(ctx, parentProject.Organization.ID).Log(audit.ResourceDeletedEvent, audit.Target{ diff --git a/internal/api/v1beta1connect/resource_test.go b/internal/api/v1beta1connect/resource_test.go index 4835a8057..b3975e0d1 100644 --- a/internal/api/v1beta1connect/resource_test.go +++ b/internal/api/v1beta1connect/resource_test.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "testing" "time" @@ -48,11 +49,12 @@ var ( func TestHandler_ListResources(t *testing.T) { tests := []struct { - name string - setup func(rs *mocks.ResourceService) - request *connect.Request[frontierv1beta1.ListResourcesRequest] - want *connect.Response[frontierv1beta1.ListResourcesResponse] - wantErr error + name string + setup func(rs *mocks.ResourceService) + request *connect.Request[frontierv1beta1.ListResourcesRequest] + want *connect.Response[frontierv1beta1.ListResourcesResponse] + wantErr error + skipErrMsgCheck bool }{ { name: "should return internal error if resource service return some error", @@ -61,9 +63,11 @@ func TestHandler_ListResources(t *testing.T) { }, request: connect.NewRequest(&frontierv1beta1.ListResourcesRequest{}), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListResources: namespace= project_id=: %w", errors.New("test error"))), }, { + // proto error message is non-deterministic (randomly uses U+00a0 or space) + // so we only check the error code name: "should return internal error if transformation fails", setup: func(rs *mocks.ResourceService) { rs.EXPECT().List(mock.AnythingOfType("context.backgroundCtx"), resource.Filter{}).Return([]resource.Resource{ @@ -74,9 +78,10 @@ func TestHandler_ListResources(t *testing.T) { }, }, nil) }, - request: connect.NewRequest(&frontierv1beta1.ListResourcesRequest{}), - want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + request: connect.NewRequest(&frontierv1beta1.ListResourcesRequest{}), + want: nil, + wantErr: connect.NewError(connect.CodeInternal, errors.New("proto error")), + skipErrMsgCheck: true, }, { name: "should return resources if resource service return nil error", @@ -103,7 +108,15 @@ func TestHandler_ListResources(t *testing.T) { mockDep := ConnectHandler{resourceService: mockResourceSrv} resp, err := mockDep.ListResources(context.Background(), tt.request) assert.EqualValues(t, tt.want, resp) - assert.EqualValues(t, tt.wantErr, err) + if tt.wantErr != nil { + assert.Error(t, err) + assert.Equal(t, connect.CodeOf(tt.wantErr), connect.CodeOf(err)) + if !tt.skipErrMsgCheck { + assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + } + } else { + assert.NoError(t, err) + } }) } } @@ -126,7 +139,7 @@ func TestConnectHandler_ListProjectResources(t *testing.T) { ProjectId: testProjectID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectResources: namespace= project_id=%s: %w", testProjectID, errors.New("test error"))), }, { name: "should return empty list if resource service returns empty slice", @@ -224,7 +237,7 @@ func TestConnectHandler_CreateProjectResource(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProjectResource.GetProject: project_id=%s: %w", testResource.ProjectID, errors.New("test error"))), }, { name: "should return internal error if resource service returns error", @@ -249,7 +262,7 @@ func TestConnectHandler_CreateProjectResource(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("CreateProjectResource: resource_id= project_id=%s resource_name=%s namespace=%s principal=%s: %w", testResource.ProjectID, testResource.Name, testResource.NamespaceID, testUserID, errors.New("test error"))), }, { name: "should return bad request error if field value not exist in foreign reference", @@ -387,11 +400,12 @@ func TestConnectHandler_CreateProjectResource(t *testing.T) { func TestConnectHandler_GetProjectResource(t *testing.T) { tests := []struct { - name string - setup func(rs *mocks.ResourceService) - request *connect.Request[frontierv1beta1.GetProjectResourceRequest] - want *connect.Response[frontierv1beta1.GetProjectResourceResponse] - wantErr error + name string + setup func(rs *mocks.ResourceService) + request *connect.Request[frontierv1beta1.GetProjectResourceRequest] + want *connect.Response[frontierv1beta1.GetProjectResourceResponse] + wantErr error + skipErrMsgCheck bool }{ { name: "should return internal error if resource service returns error", @@ -402,7 +416,7 @@ func TestConnectHandler_GetProjectResource(t *testing.T) { Id: testResource.ID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("GetProjectResource: resource_id=%s: %w", testResource.ID, errors.New("test error"))), }, { name: "should return not found error if id is empty", @@ -449,6 +463,8 @@ func TestConnectHandler_GetProjectResource(t *testing.T) { wantErr: nil, }, { + // proto error message is non-deterministic (randomly uses U+00a0 or space) + // so we only check the error code name: "should return internal error if transform fails", setup: func(rs *mocks.ResourceService) { invalidResource := testResource @@ -457,11 +473,12 @@ func TestConnectHandler_GetProjectResource(t *testing.T) { } rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), testResource.ID).Return(invalidResource, nil) }, - request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{ + request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{ Id: testResource.ID, }), - want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + want: nil, + wantErr: connect.NewError(connect.CodeInternal, errors.New("proto error")), + skipErrMsgCheck: true, }, } @@ -476,7 +493,9 @@ func TestConnectHandler_GetProjectResource(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + if !tt.skipErrMsgCheck { + assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + } } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, resp) @@ -517,7 +536,7 @@ func TestConnectHandler_UpdateProjectResource(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProjectResource.GetProject: project_id=%s: %w", testResource.ProjectID, errors.New("test error"))), }, { name: "should return internal error if resource service returns error", @@ -544,7 +563,7 @@ func TestConnectHandler_UpdateProjectResource(t *testing.T) { }, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProjectResource: resource_id=%s project_id=%s resource_name=%s namespace=%s principal=%s: %w", testResourceID, testResource.ProjectID, testResource.Name, testResource.NamespaceID, testUserID, errors.New("test error"))), }, { name: "should return not found error if resource not exist", @@ -758,7 +777,7 @@ func TestConnectHandler_DeleteProjectResource(t *testing.T) { Id: testResource.ID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProjectResource.GetResource: resource_id=%s: %w", testResource.ID, errors.New("test error"))), }, { name: "should return not found error if resource not exist", @@ -801,7 +820,7 @@ func TestConnectHandler_DeleteProjectResource(t *testing.T) { Id: testResource.ID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProjectResource.GetProject: resource_id=%s project_id=%s: %w", testResource.ID, testResource.ProjectID, errors.New("test error"))), }, { name: "should return internal error if resource service Delete returns error", @@ -819,7 +838,7 @@ func TestConnectHandler_DeleteProjectResource(t *testing.T) { Id: testResource.ID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteProjectResource: resource_id=%s project_id=%s namespace=%s: %w", testResource.ID, testResource.ProjectID, testResource.NamespaceID, errors.New("delete error"))), }, { name: "should return success if resource is deleted successfully", diff --git a/internal/api/v1beta1connect/role.go b/internal/api/v1beta1connect/role.go index 1d01c14c5..748fb9f6f 100644 --- a/internal/api/v1beta1connect/role.go +++ b/internal/api/v1beta1connect/role.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "errors" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/audit" @@ -60,19 +61,13 @@ func (h *ConnectHandler) CreateRole(ctx context.Context, request *connect.Reques case errors.Is(err, role.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, err) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateRole", err, - "role_name", request.Msg.GetBody().GetName(), - "role_title", request.Msg.GetBody().GetTitle(), - "permissions", request.Msg.GetBody().GetPermissions(), - "scopes", request.Msg.GetBody().GetScopes()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateRole: role_name=%s role_title=%s permissions=%v scopes=%v: %w", request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetPermissions(), request.Msg.GetBody().GetScopes(), err)) } } rolePB, err := transformRoleToPB(newRole) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateRole", newRole.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateRole: entity_id=%s: %w", newRole.ID, err)) } audit.GetAuditor(ctx, schema.PlatformOrgID.String()).Log(audit.RoleCreatedEvent, audit.Target{ @@ -122,20 +117,13 @@ func (h *ConnectHandler) UpdateRole(ctx context.Context, request *connect.Reques case errors.Is(err, role.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdateRole", err, - "role_id", request.Msg.GetId(), - "role_name", request.Msg.GetBody().GetName(), - "role_title", request.Msg.GetBody().GetTitle(), - "permissions", request.Msg.GetBody().GetPermissions(), - "scopes", request.Msg.GetBody().GetScopes()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateRole: role_id=%s role_name=%s role_title=%s permissions=%v scopes=%v: %w", request.Msg.GetId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetPermissions(), request.Msg.GetBody().GetScopes(), err)) } } rolePB, err := transformRoleToPB(updatedRole) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateRole", updatedRole.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateRole: entity_id=%s: %w", updatedRole.ID, err)) } audit.GetAuditor(ctx, schema.PlatformOrgID.String()).Log(audit.RoleUpdatedEvent, audit.Target{ @@ -167,7 +155,6 @@ func transformRoleToPB(from role.Role) (frontierv1beta1.Role, error) { } func (h *ConnectHandler) ListRoles(ctx context.Context, request *connect.Request[frontierv1beta1.ListRolesRequest]) (*connect.Response[frontierv1beta1.ListRolesResponse], error) { - errorLogger := NewErrorLogger() var roles []*frontierv1beta1.Role roleList, err := h.roleService.List(ctx, role.Filter{ @@ -175,16 +162,13 @@ func (h *ConnectHandler) ListRoles(ctx context.Context, request *connect.Request Scopes: request.Msg.GetScopes(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListRoles", err, - "scopes", request.Msg.GetScopes()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListRoles: scopes=%v: %w", request.Msg.GetScopes(), err)) } for _, v := range roleList { rolePB, err := transformRoleToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListRoles", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListRoles: entity_id=%s: %w", v.ID, err)) } roles = append(roles, &rolePB) @@ -194,7 +178,6 @@ func (h *ConnectHandler) ListRoles(ctx context.Context, request *connect.Request } func (h *ConnectHandler) ListOrganizationRoles(ctx context.Context, request *connect.Request[frontierv1beta1.ListOrganizationRolesRequest]) (*connect.Response[frontierv1beta1.ListOrganizationRolesResponse], error) { - errorLogger := NewErrorLogger() var roles []*frontierv1beta1.Role roleList, err := h.roleService.List(ctx, role.Filter{ @@ -202,17 +185,13 @@ func (h *ConnectHandler) ListOrganizationRoles(ctx context.Context, request *con Scopes: request.Msg.GetScopes(), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListOrganizationRoles", err, - "org_id", request.Msg.GetOrgId(), - "scopes", request.Msg.GetScopes()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationRoles: org_id=%s scopes=%v: %w", request.Msg.GetOrgId(), request.Msg.GetScopes(), err)) } for _, v := range roleList { rolePB, err := transformRoleToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationRoles", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationRoles: entity_id=%s: %w", v.ID, err)) } roles = append(roles, &rolePB) @@ -237,9 +216,7 @@ func (h *ConnectHandler) CreateOrganizationRole(ctx context.Context, request *co // Fetch organization to get name for audit record org, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateOrganizationRole.GetOrganization", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationRole.GetOrganization: org_id=%s: %w", request.Msg.GetOrgId(), err)) } metaDataMap[orgNameMetadataKey] = org.Title @@ -268,20 +245,13 @@ func (h *ConnectHandler) CreateOrganizationRole(ctx context.Context, request *co case errors.Is(err, role.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateOrganizationRole", err, - "org_id", request.Msg.GetOrgId(), - "role_name", request.Msg.GetBody().GetName(), - "role_title", request.Msg.GetBody().GetTitle(), - "permissions", request.Msg.GetBody().GetPermissions(), - "scopes", request.Msg.GetBody().GetScopes()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationRole: org_id=%s role_name=%s role_title=%s permissions=%v scopes=%v: %w", request.Msg.GetOrgId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetPermissions(), request.Msg.GetBody().GetScopes(), err)) } } rolePB, err := transformRoleToPB(newRole) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateOrganizationRole", newRole.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateOrganizationRole: entity_id=%s: %w", newRole.ID, err)) } audit.GetAuditor(ctx, request.Msg.GetOrgId()).Log(audit.RoleCreatedEvent, audit.Target{ @@ -305,16 +275,13 @@ func (h *ConnectHandler) GetOrganizationRole(ctx context.Context, request *conne case errors.Is(err, role.ErrNotExist), errors.Is(err, role.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetOrganizationRole", err, - "role_id", roleID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationRole: role_id=%s: %w", roleID, err)) } } rolePB, err := transformRoleToPB(fetchedRole) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetOrganizationRole", fetchedRole.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrganizationRole: entity_id=%s: %w", fetchedRole.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetOrganizationRoleResponse{Role: &rolePB}), nil @@ -339,9 +306,7 @@ func (h *ConnectHandler) UpdateOrganizationRole(ctx context.Context, request *co // Fetch organization to get name for audit record org, err := h.orgService.Get(ctx, request.Msg.GetOrgId()) if err != nil { - errorLogger.LogServiceError(ctx, request, "UpdateOrganizationRole.GetOrganization", err, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateOrganizationRole.GetOrganization: org_id=%s: %w", request.Msg.GetOrgId(), err)) } metaDataMap[orgNameMetadataKey] = org.Title @@ -372,21 +337,13 @@ func (h *ConnectHandler) UpdateOrganizationRole(ctx context.Context, request *co case errors.Is(err, role.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdateOrganizationRole", err, - "role_id", request.Msg.GetId(), - "org_id", request.Msg.GetOrgId(), - "role_name", request.Msg.GetBody().GetName(), - "role_title", request.Msg.GetBody().GetTitle(), - "permissions", request.Msg.GetBody().GetPermissions(), - "scopes", request.Msg.GetBody().GetScopes()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateOrganizationRole: role_id=%s org_id=%s role_name=%s role_title=%s permissions=%v scopes=%v: %w", request.Msg.GetId(), request.Msg.GetOrgId(), request.Msg.GetBody().GetName(), request.Msg.GetBody().GetTitle(), request.Msg.GetBody().GetPermissions(), request.Msg.GetBody().GetScopes(), err)) } } rolePB, err := transformRoleToPB(updatedRole) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateOrganizationRole", updatedRole.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateOrganizationRole: entity_id=%s: %w", updatedRole.ID, err)) } audit.GetAuditor(ctx, request.Msg.GetOrgId()).Log(audit.RoleUpdatedEvent, audit.Target{ @@ -419,10 +376,7 @@ func (h *ConnectHandler) DeleteOrganizationRole(ctx context.Context, request *co case errors.Is(err, role.ErrRoleInUse): return nil, connect.NewError(connect.CodeFailedPrecondition, role.ErrRoleInUse) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteOrganizationRole", err, - "role_id", roleID, - "org_id", orgID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteOrganizationRole: role_id=%s org_id=%s: %w", roleID, orgID, err)) } } @@ -453,9 +407,7 @@ func (h *ConnectHandler) DeleteRole(ctx context.Context, request *connect.Reques case errors.Is(err, role.ErrRoleInUse): return nil, connect.NewError(connect.CodeFailedPrecondition, role.ErrRoleInUse) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteRole", err, - "role_id", roleID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteRole: role_id=%s: %w", roleID, err)) } } diff --git a/internal/api/v1beta1connect/role_test.go b/internal/api/v1beta1connect/role_test.go index 9d90ef133..28e84cbca 100644 --- a/internal/api/v1beta1connect/role_test.go +++ b/internal/api/v1beta1connect/role_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -214,7 +215,7 @@ func TestHandler_ListRoles(t *testing.T) { Scopes: []string{}, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListRoles: scopes=%v: %w", []string{}, ErrInternalServerError)), }, } @@ -268,7 +269,7 @@ func TestHandler_DeleteRole(t *testing.T) { Id: testRoleID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteRole: role_id=%s: %w", testRoleID, ErrInternalServerError)), }, { name: "should return nil if role service return nil", diff --git a/internal/api/v1beta1connect/serviceuser.go b/internal/api/v1beta1connect/serviceuser.go index 30bd3a5b3..653297be3 100644 --- a/internal/api/v1beta1connect/serviceuser.go +++ b/internal/api/v1beta1connect/serviceuser.go @@ -3,6 +3,7 @@ package v1beta1connect import ( "context" "encoding/json" + "fmt" "connectrpc.com/connect" "github.com/lestrrat-go/jwx/v2/jwk" @@ -38,24 +39,19 @@ func toJSONWebKey(keySet jwk.Set) (*JsonWebKeySet, error) { } func (h *ConnectHandler) ListServiceUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListServiceUsersRequest]) (*connect.Response[frontierv1beta1.ListServiceUsersResponse], error) { - errorLogger := NewErrorLogger() var users []*frontierv1beta1.ServiceUser usersList, err := h.serviceUserService.List(ctx, serviceuser.Filter{ OrgID: request.Msg.GetOrgId(), State: serviceuser.State(request.Msg.GetState()), }) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListServiceUsers", err, - "org_id", request.Msg.GetOrgId(), - "state", request.Msg.GetState()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUsers: org_id=%s state=%s: %w", request.Msg.GetOrgId(), request.Msg.GetState(), err)) } for _, user := range usersList { userPB, err := transformServiceUserToPB(user) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListServiceUsers", user.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUsers: entity_id=%s: %w", user.ID, err)) } users = append(users, userPB) } @@ -66,19 +62,16 @@ func (h *ConnectHandler) ListServiceUsers(ctx context.Context, request *connect. } func (h *ConnectHandler) ListAllServiceUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListAllServiceUsersRequest]) (*connect.Response[frontierv1beta1.ListAllServiceUsersResponse], error) { - errorLogger := NewErrorLogger() var serviceUsers []*frontierv1beta1.ServiceUser serviceUsersList, err := h.serviceUserService.ListAll(ctx) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListAllServiceUsers", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllServiceUsers: %w", err)) } for _, su := range serviceUsersList { serviceUserPB, err := transformServiceUserToPB(su) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListAllServiceUsers", su.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllServiceUsers: entity_id=%s: %w", su.ID, err)) } serviceUsers = append(serviceUsers, serviceUserPB) } @@ -103,16 +96,13 @@ func (h *ConnectHandler) GetServiceUser(ctx context.Context, request *connect.Re case errors.Is(err, serviceuser.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrServiceUserNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetServiceUser", err, - "service_user_id", serviceUserID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetServiceUser: service_user_id=%s: %w", serviceUserID, err)) } } svUserPb, err := transformServiceUserToPB(svUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetServiceUser", svUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetServiceUser: entity_id=%s: %w", svUser.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetServiceUserResponse{ Serviceuser: svUserPb, @@ -159,14 +149,13 @@ func (h *ConnectHandler) CreateServiceUser(ctx context.Context, request *connect case errors.Is(err, organization.ErrDisabled): return nil, connect.NewError(connect.CodeFailedPrecondition, ErrOrgDisabled) default: - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateServiceUser: %w", err)) } } svUserPb, err := transformServiceUserToPB(svUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateServiceUser", svUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateServiceUser: entity_id=%s: %w", svUser.ID, err)) } audit.GetAuditor(ctx, request.Msg.GetOrgId()). @@ -194,10 +183,7 @@ func (h *ConnectHandler) DeleteServiceUser(ctx context.Context, request *connect case err == serviceuser.ErrNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrServiceUserNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteServiceUser", err, - "service_user_id", serviceUserID, - "org_id", orgID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteServiceUser: service_user_id=%s org_id=%s: %w", serviceUserID, orgID, err)) } } @@ -225,10 +211,7 @@ func (h *ConnectHandler) CreateServiceUserJWK(ctx context.Context, request *conn case err == serviceuser.ErrNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrServiceUserCredNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateServiceUserJWK", err, - "service_user_id", serviceUserID, - "title", title) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateServiceUserJWK: service_user_id=%s title=%s: %w", serviceUserID, title, err)) } } @@ -257,19 +240,14 @@ func (h *ConnectHandler) ListServiceUserJWKs(ctx context.Context, request *conne case err == serviceuser.ErrNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrServiceUserCredNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "ListServiceUserJWKs", err, - "service_user_id", serviceUserID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUserJWKs: service_user_id=%s: %w", serviceUserID, err)) } } for _, svCred := range credList { jwkJson, err := json.Marshal(svCred.PublicKey) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListServiceUserJWKs.MarshalPublicKey", err, - "service_user_id", serviceUserID, - "credential_id", svCred.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUserJWKs.MarshalPublicKey: service_user_id=%s credential_id=%s: %w", serviceUserID, svCred.ID, err)) } keys = append(keys, &frontierv1beta1.ServiceUserJWK{ Id: svCred.ID, @@ -297,18 +275,13 @@ func (h *ConnectHandler) GetServiceUserJWK(ctx context.Context, request *connect case err == serviceuser.ErrCredNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrServiceUserCredNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "GetServiceUserJWK", err, - "key_id", keyID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetServiceUserJWK: key_id=%s: %w", keyID, err)) } } jwks, err := toJSONWebKey(svCred.PublicKey) if err != nil { - errorLogger.LogServiceError(ctx, request, "GetServiceUserJWK.ToJSONWebKey", err, - "key_id", keyID, - "credential_id", svCred.ID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetServiceUserJWK.ToJSONWebKey: key_id=%s credential_id=%s: %w", keyID, svCred.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetServiceUserJWKResponse{ Keys: jwks.Keys, @@ -328,9 +301,7 @@ func (h *ConnectHandler) DeleteServiceUserJWK(ctx context.Context, request *conn case err == serviceuser.ErrCredNotExist: return nil, connect.NewError(connect.CodeNotFound, ErrServiceUserCredNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteServiceUserJWK", err, - "key_id", keyID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteServiceUserJWK: key_id=%s: %w", keyID, err)) } } @@ -338,7 +309,6 @@ func (h *ConnectHandler) DeleteServiceUserJWK(ctx context.Context, request *conn } func (h *ConnectHandler) CreateServiceUserCredential(ctx context.Context, request *connect.Request[frontierv1beta1.CreateServiceUserCredentialRequest]) (*connect.Response[frontierv1beta1.CreateServiceUserCredentialResponse], error) { - errorLogger := NewErrorLogger() serviceUserID := request.Msg.GetId() title := request.Msg.GetTitle() @@ -347,10 +317,7 @@ func (h *ConnectHandler) CreateServiceUserCredential(ctx context.Context, reques Title: title, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateServiceUserCredential", err, - "service_user_id", serviceUserID, - "title", title) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateServiceUserCredential: service_user_id=%s title=%s: %w", serviceUserID, title, err)) } return connect.NewResponse(&frontierv1beta1.CreateServiceUserCredentialResponse{ @@ -364,14 +331,11 @@ func (h *ConnectHandler) CreateServiceUserCredential(ctx context.Context, reques } func (h *ConnectHandler) ListServiceUserCredentials(ctx context.Context, request *connect.Request[frontierv1beta1.ListServiceUserCredentialsRequest]) (*connect.Response[frontierv1beta1.ListServiceUserCredentialsResponse], error) { - errorLogger := NewErrorLogger() serviceUserID := request.Msg.GetId() credentials, err := h.serviceUserService.ListSecret(ctx, serviceUserID) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListServiceUserCredentials", err, - "service_user_id", serviceUserID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUserCredentials: service_user_id=%s: %w", serviceUserID, err)) } secretsPB := make([]*frontierv1beta1.SecretCredential, 0, len(credentials)) for _, sec := range credentials { @@ -387,20 +351,16 @@ func (h *ConnectHandler) ListServiceUserCredentials(ctx context.Context, request } func (h *ConnectHandler) DeleteServiceUserCredential(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteServiceUserCredentialRequest]) (*connect.Response[frontierv1beta1.DeleteServiceUserCredentialResponse], error) { - errorLogger := NewErrorLogger() secretID := request.Msg.GetSecretId() err := h.serviceUserService.DeleteSecret(ctx, secretID) if err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteServiceUserCredential", err, - "secret_id", secretID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteServiceUserCredential: secret_id=%s: %w", secretID, err)) } return connect.NewResponse(&frontierv1beta1.DeleteServiceUserCredentialResponse{}), nil } func (h *ConnectHandler) CreateServiceUserToken(ctx context.Context, request *connect.Request[frontierv1beta1.CreateServiceUserTokenRequest]) (*connect.Response[frontierv1beta1.CreateServiceUserTokenResponse], error) { - errorLogger := NewErrorLogger() serviceUserID := request.Msg.GetId() title := request.Msg.GetTitle() @@ -409,10 +369,7 @@ func (h *ConnectHandler) CreateServiceUserToken(ctx context.Context, request *co Title: title, }) if err != nil { - errorLogger.LogServiceError(ctx, request, "CreateServiceUserToken", err, - "service_user_id", serviceUserID, - "title", title) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateServiceUserToken: service_user_id=%s title=%s: %w", serviceUserID, title, err)) } return connect.NewResponse(&frontierv1beta1.CreateServiceUserTokenResponse{ Token: &frontierv1beta1.ServiceUserToken{ @@ -425,14 +382,11 @@ func (h *ConnectHandler) CreateServiceUserToken(ctx context.Context, request *co } func (h *ConnectHandler) ListServiceUserTokens(ctx context.Context, request *connect.Request[frontierv1beta1.ListServiceUserTokensRequest]) (*connect.Response[frontierv1beta1.ListServiceUserTokensResponse], error) { - errorLogger := NewErrorLogger() serviceUserID := request.Msg.GetId() credentials, err := h.serviceUserService.ListToken(ctx, serviceUserID) if err != nil { - errorLogger.LogServiceError(ctx, request, "ListServiceUserTokens", err, - "service_user_id", serviceUserID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUserTokens: service_user_id=%s: %w", serviceUserID, err)) } secretsPB := make([]*frontierv1beta1.ServiceUserToken, 0, len(credentials)) for _, sec := range credentials { @@ -448,14 +402,11 @@ func (h *ConnectHandler) ListServiceUserTokens(ctx context.Context, request *con } func (h *ConnectHandler) DeleteServiceUserToken(ctx context.Context, request *connect.Request[frontierv1beta1.DeleteServiceUserTokenRequest]) (*connect.Response[frontierv1beta1.DeleteServiceUserTokenResponse], error) { - errorLogger := NewErrorLogger() tokenID := request.Msg.GetTokenId() err := h.serviceUserService.DeleteToken(ctx, tokenID) if err != nil { - errorLogger.LogServiceError(ctx, request, "DeleteServiceUserToken", err, - "token_id", tokenID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteServiceUserToken: token_id=%s: %w", tokenID, err)) } return connect.NewResponse(&frontierv1beta1.DeleteServiceUserTokenResponse{}), nil } @@ -482,10 +433,7 @@ func (h *ConnectHandler) ListServiceUserProjects(ctx context.Context, request *c errors.Is(err, project.ErrInvalidPrincipalType): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "ListServiceUserProjects", err, - "service_user_id", serviceUserID, - "org_id", orgID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUserProjects: service_user_id=%s org_id=%s: %w", serviceUserID, orgID, err)) } } @@ -494,8 +442,7 @@ func (h *ConnectHandler) ListServiceUserProjects(ctx context.Context, request *c for _, v := range projList { projPB, err := transformProjectToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListServiceUserProjects", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListServiceUserProjects: entity_id=%s: %w", v.ID, err)) } projects = append(projects, projPB) } diff --git a/internal/api/v1beta1connect/serviceuser_test.go b/internal/api/v1beta1connect/serviceuser_test.go index 88b1337d7..be83cfe2c 100644 --- a/internal/api/v1beta1connect/serviceuser_test.go +++ b/internal/api/v1beta1connect/serviceuser_test.go @@ -527,7 +527,7 @@ func TestConnectHandler_CreateServiceUserJWK(t *testing.T) { }).Return(serviceuser.Credential{}, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -616,7 +616,7 @@ func TestConnectHandler_ListServiceUserJWKs(t *testing.T) { su.EXPECT().ListKeys(mock.Anything, "1").Return(nil, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -705,7 +705,7 @@ func TestHandler_GetServiceUserJWK(t *testing.T) { su.On("GetKey", mock.Anything, "1").Return(serviceuser.Credential{}, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -786,7 +786,7 @@ func TestHandler_DeleteServiceUserJWK(t *testing.T) { su.On("DeleteKey", mock.Anything, "1").Return(errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -864,7 +864,7 @@ func TestHandler_CreateServiceUserCredential(t *testing.T) { }, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -936,7 +936,7 @@ func TestHandler_ListServiceUserCredentials(t *testing.T) { su.On("ListSecret", mock.Anything, "service-user-id").Return(nil, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -1031,7 +1031,7 @@ func TestHandler_DeleteServiceUserCredential(t *testing.T) { su.On("DeleteSecret", mock.Anything, "credential-id").Return(errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -1092,7 +1092,7 @@ func TestHandler_CreateServiceUserToken(t *testing.T) { }).Return(serviceuser.Token{}, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -1164,7 +1164,7 @@ func TestHandler_ListServiceUserTokens(t *testing.T) { su.On("ListToken", mock.Anything, "service-user-id").Return(nil, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -1258,7 +1258,7 @@ func TestHandler_DeleteServiceUserToken(t *testing.T) { su.On("DeleteToken", mock.Anything, "token-id").Return(errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { @@ -1329,7 +1329,7 @@ func TestHandler_GetServiceUser(t *testing.T) { }, request: connect.NewRequest(&frontierv1beta1.GetServiceUserRequest{Id: testServiceUserID}), errCode: connect.CodeInternal, - wantErr: ErrInternalServerError, + wantErr: errors.New("boom"), }, } for _, tt := range tests { @@ -1391,7 +1391,7 @@ func TestHandler_ListServiceUserProjects(t *testing.T) { projSvc.EXPECT().List(mock.Anything, project.Filter{Principal: &authenticate.Principal{ID: "1", Type: schema.ServiceUserPrincipal}}).Return(nil, errors.New("test error")) }, want: nil, - wantErr: ErrInternalServerError, + wantErr: errors.New("test error"), errCode: connect.CodeInternal, }, { diff --git a/internal/api/v1beta1connect/session.go b/internal/api/v1beta1connect/session.go index 14673251e..0528f271c 100644 --- a/internal/api/v1beta1connect/session.go +++ b/internal/api/v1beta1connect/session.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "strings" "time" @@ -33,10 +34,7 @@ func (h *ConnectHandler) ListSessions(ctx context.Context, request *connect.Requ // Fetch all active sessions for the authenticated user sessions, err := h.sessionService.List(ctx, principal.ID) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListSessions.List", err, - "principal_id", principal.ID, - "principal_type", principal.Type) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListSessions.List: principal_id=%s principal_type=%s: %w", principal.ID, principal.Type, err)) } // Transform domain sessions to protobuf sessions @@ -44,8 +42,7 @@ func (h *ConnectHandler) ListSessions(ctx context.Context, request *connect.Requ for _, session := range sessions { pbSession, err := transformSessionToPB(session, currentSessionID) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListSessions", session.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListSessions: entity_id=%s: %w", session.ID.String(), err)) } pbSessions = append(pbSessions, pbSession) } @@ -113,11 +110,7 @@ func (h *ConnectHandler) RevokeSession(ctx context.Context, request *connect.Req } if err := h.sessionService.Delete(ctx, sessionID); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "RevokeSession", err, - "session_id", sessionID.String(), - "principal_id", principal.ID, - "principal_type", principal.Type) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RevokeSession: session_id=%s principal_id=%s principal_type=%s: %w", sessionID.String(), principal.ID, principal.Type, err)) } return connect.NewResponse(&frontierv1beta1.RevokeSessionResponse{}), nil @@ -140,17 +133,13 @@ func (h *ConnectHandler) PingUserSession(ctx context.Context, request *connect.R sessionMetadata := sessionutils.ExtractSessionMetadata(ctx, request, h.authConfig.Session.Headers) if err := h.sessionService.Ping(ctx, session.ID, sessionMetadata); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "PingUserSession", err, - "session_id", session.ID.String()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("PingUserSession: session_id=%s: %w", session.ID.String(), err)) } // Fetch updated session to get latest metadata updatedSession, err := h.sessionService.GetByID(ctx, session.ID) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "PingUserSession.GetByID", err, - "session_id", session.ID.String()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("PingUserSession.GetByID: session_id=%s: %w", session.ID.String(), err)) } // Convert session metadata to proto format @@ -164,8 +153,6 @@ func (h *ConnectHandler) PingUserSession(ctx context.Context, request *connect.R // Admin APIs // Returns a list of all sessions for a specific user. func (h *ConnectHandler) ListUserSessions(ctx context.Context, request *connect.Request[frontierv1beta1.ListUserSessionsRequest]) (*connect.Response[frontierv1beta1.ListUserSessionsResponse], error) { - errorLogger := NewErrorLogger() - // Manual validation for user_id since protobuf validation is not working userID := request.Msg.GetUserId() if userID == "" { @@ -179,17 +166,14 @@ func (h *ConnectHandler) ListUserSessions(ctx context.Context, request *connect. sessions, err := h.sessionService.List(ctx, userID) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListUserSessions", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserSessions: user_id=%s: %w", userID, err)) } var pbSessions []*frontierv1beta1.Session for _, session := range sessions { pbSession, err := transformSessionToPB(session, "") if err != nil { - errorLogger.LogTransformError(ctx, request, "ListUserSessions", session.ID.String(), err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserSessions: entity_id=%s: %w", session.ID.String(), err)) } pbSessions = append(pbSessions, pbSession) } @@ -201,17 +185,13 @@ func (h *ConnectHandler) ListUserSessions(ctx context.Context, request *connect. // Revoke a specific session for a specific user (admin only). func (h *ConnectHandler) RevokeUserSession(ctx context.Context, request *connect.Request[frontierv1beta1.RevokeUserSessionRequest]) (*connect.Response[frontierv1beta1.RevokeUserSessionResponse], error) { - errorLogger := NewErrorLogger() - sessionID, err := uuid.Parse(request.Msg.GetSessionId()) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, ErrInvalidSessionID) } if err := h.sessionService.Delete(ctx, sessionID); err != nil { - errorLogger.LogUnexpectedError(ctx, request, "RevokeUserSession", err, - "session_id", sessionID.String()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RevokeUserSession: session_id=%s: %w", sessionID.String(), err)) } return connect.NewResponse(&frontierv1beta1.RevokeUserSessionResponse{}), nil diff --git a/internal/api/v1beta1connect/user.go b/internal/api/v1beta1connect/user.go index 15b0b85e5..2b696e6b4 100644 --- a/internal/api/v1beta1connect/user.go +++ b/internal/api/v1beta1connect/user.go @@ -30,7 +30,6 @@ import ( ) func (h *ConnectHandler) ListAllUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListAllUsersRequest]) (*connect.Response[frontierv1beta1.ListAllUsersResponse], error) { - errorLogger := NewErrorLogger() var users []*frontierv1beta1.User var usersList []user.User @@ -49,17 +48,13 @@ func (h *ConnectHandler) ListAllUsers(ctx context.Context, request *connect.Requ }) } if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListAllUsers", err, - "org_id", request.Msg.GetOrgId(), - "group_id", request.Msg.GetGroupId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllUsers: org_id=%s group_id=%s: %w", request.Msg.GetOrgId(), request.Msg.GetGroupId(), err)) } for _, user := range usersList { userPB, err := transformUserToPB(user) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListAllUsers", user.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListAllUsers: entity_id=%s: %w", user.ID, err)) } users = append(users, userPB) } @@ -71,19 +66,15 @@ func (h *ConnectHandler) ListAllUsers(ctx context.Context, request *connect.Requ } func (h *ConnectHandler) GetCurrentAdminUser(ctx context.Context, request *connect.Request[frontierv1beta1.GetCurrentAdminUserRequest]) (*connect.Response[frontierv1beta1.GetCurrentAdminUserResponse], error) { - errorLogger := NewErrorLogger() - principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "GetCurrentAdminUser", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentAdminUser: %w", err)) } if principal.Type == schema.ServiceUserPrincipal { serviceUserPB, err := transformServiceUserToPB(*principal.ServiceUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetCurrentAdminUser", principal.ServiceUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentAdminUser: entity_id=%s: %w", principal.ServiceUser.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetCurrentAdminUserResponse{ ServiceUser: serviceUserPB, @@ -92,8 +83,7 @@ func (h *ConnectHandler) GetCurrentAdminUser(ctx context.Context, request *conne userPB, err := transformUserToPB(*principal.User) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetCurrentAdminUser", principal.User.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentAdminUser: entity_id=%s: %w", principal.User.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetCurrentAdminUserResponse{ @@ -151,16 +141,12 @@ func (h *ConnectHandler) CreateUser(ctx context.Context, request *connect.Reques case errors.Is(errors.Unwrap(err), user.ErrKeyDoesNotExists): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "CreateUser", err, - "user_email", email, - "user_name", name) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateUser: user_email=%s user_name=%s: %w", email, name, err)) } } transformedUser, err := transformUserToPB(newUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "CreateUser", newUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateUser: entity_id=%s: %w", newUser.ID, err)) } audit.GetAuditor(ctx, schema.PlatformOrgID.String()). LogWithAttrs(audit.UserCreatedEvent, audit.UserTarget(newUser.ID), map[string]string{ @@ -185,16 +171,13 @@ func (h *ConnectHandler) GetUser(ctx context.Context, request *connect.Request[f case errors.Is(err, user.ErrNotExist), errors.Is(err, user.ErrInvalidUUID), errors.Is(err, user.ErrInvalidID): return nil, connect.NewError(connect.CodeNotFound, ErrUserNotExist) default: - errorLogger.LogUnexpectedError(ctx, request, "GetUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetUser: user_id=%s: %w", userID, err)) } } userPB, err := transformUserToPB(fetchedUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetUser", fetchedUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetUser: entity_id=%s: %w", fetchedUser.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetUserResponse{ @@ -203,19 +186,15 @@ func (h *ConnectHandler) GetUser(ctx context.Context, request *connect.Request[f } func (h *ConnectHandler) GetCurrentUser(ctx context.Context, request *connect.Request[frontierv1beta1.GetCurrentUserRequest]) (*connect.Response[frontierv1beta1.GetCurrentUserResponse], error) { - errorLogger := NewErrorLogger() - principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "GetCurrentUser", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentUser: %w", err)) } if principal.Type == schema.ServiceUserPrincipal { serviceUserPB, err := transformServiceUserToPB(*principal.ServiceUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetCurrentUser", principal.ServiceUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentUser: entity_id=%s: %w", principal.ServiceUser.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetCurrentUserResponse{ Serviceuser: serviceUserPB, @@ -224,8 +203,7 @@ func (h *ConnectHandler) GetCurrentUser(ctx context.Context, request *connect.Re userPB, err := transformUserToPB(*principal.User) if err != nil { - errorLogger.LogTransformError(ctx, request, "GetCurrentUser", principal.User.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentUser: entity_id=%s: %w", principal.User.ID, err)) } return connect.NewResponse(&frontierv1beta1.GetCurrentUserResponse{ User: userPB, @@ -268,9 +246,7 @@ func (h *ConnectHandler) UpdateUser(ctx context.Context, request *connect.Reques } return connect.NewResponse(&frontierv1beta1.UpdateUserResponse{User: createUserResponse.Msg.GetUser()}), nil } else { - errorLogger.LogServiceError(ctx, request, "UpdateUser.GetByEmail", err, - "lookup_email", id) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateUser.GetByEmail: lookup_email=%s: %w", id, err)) } } // if email in request body is different from that of user getting updated @@ -301,17 +277,13 @@ func (h *ConnectHandler) UpdateUser(ctx context.Context, request *connect.Reques case errors.Is(err, user.ErrConflict): return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdateUser", err, - "user_id", id, - "user_email", email) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateUser: user_id=%s user_email=%s: %w", id, email, err)) } } userPB, err := transformUserToPB(updatedUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateUser", updatedUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateUser: entity_id=%s: %w", updatedUser.ID, err)) } auditor.LogWithAttrs(audit.UserUpdatedEvent, audit.UserTarget(updatedUser.ID), map[string]string{ @@ -368,17 +340,13 @@ func (h *ConnectHandler) UpdateCurrentUser(ctx context.Context, request *connect case errors.Is(err, user.ErrInvalidDetails): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "UpdateCurrentUser", err, - "principal_id", principal.ID, - "principal_type", principal.Type) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateCurrentUser: principal_id=%s principal_type=%s: %w", principal.ID, principal.Type, err)) } } userPB, err := transformUserToPB(updatedUser) if err != nil { - errorLogger.LogTransformError(ctx, request, "UpdateCurrentUser", updatedUser.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateCurrentUser: entity_id=%s: %w", updatedUser.ID, err)) } auditor.LogWithAttrs(audit.UserUpdatedEvent, audit.UserTarget(updatedUser.ID), map[string]string{ @@ -404,9 +372,7 @@ func (h *ConnectHandler) EnableUser(ctx context.Context, request *connect.Reques case errors.Is(err, user.ErrInvalidID): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "EnableUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableUser: user_id=%s: %w", userID, err)) } } return connect.NewResponse(&frontierv1beta1.EnableUserResponse{}), nil @@ -426,9 +392,7 @@ func (h *ConnectHandler) DisableUser(ctx context.Context, request *connect.Reque case errors.Is(err, user.ErrInvalidID): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "DisableUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DisableUser: user_id=%s: %w", userID, err)) } } return connect.NewResponse(&frontierv1beta1.DisableUserResponse{}), nil @@ -448,9 +412,7 @@ func (h *ConnectHandler) DeleteUser(ctx context.Context, request *connect.Reques case errors.Is(err, user.ErrInvalidID): return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) default: - errorLogger.LogUnexpectedError(ctx, request, "DeleteUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteUser: user_id=%s: %w", userID, err)) } } @@ -476,18 +438,14 @@ func (h *ConnectHandler) ListUserGroups(ctx context.Context, request *connect.Re case errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "ListUserGroups", err, - "user_id", request.Msg.GetId(), - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserGroups: user_id=%s org_id=%s: %w", request.Msg.GetId(), request.Msg.GetOrgId(), err)) } } for _, group := range groupsList { groupPB, err := transformGroupToPB(group) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListUserGroups", group.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUserGroups: entity_id=%s: %w", group.ID, err)) } groups = append(groups, &groupPB) @@ -523,18 +481,14 @@ func (h *ConnectHandler) ListCurrentUserGroups(ctx context.Context, request *con case errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "ListCurrentUserGroups", err, - "principal_id", principal.ID, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserGroups: principal_id=%s org_id=%s: %w", principal.ID, request.Msg.GetOrgId(), err)) } } for _, group := range groupsList { groupPB, err := transformGroupToPB(group) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListCurrentUserGroups", group.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserGroups: entity_id=%s: %w", group.ID, err)) } groupsPb = append(groupsPb, &groupPB) @@ -546,10 +500,7 @@ func (h *ConnectHandler) ListCurrentUserGroups(ctx context.Context, request *con }) successCheckPairs, err := h.fetchAccessPairsOnResource(ctx, schema.GroupNamespace, resourceIds, request.Msg.GetWithPermissions()) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListCurrentUserGroups", err, - "principal_id", principal.ID, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListCurrentUserGroups: principal_id=%s org_id=%s: %w", principal.ID, request.Msg.GetOrgId(), err)) } permsByGroup := map[string][]string{} groupOrder := make([]string, 0, len(groupsList)) @@ -574,7 +525,6 @@ func (h *ConnectHandler) ListCurrentUserGroups(ctx context.Context, request *con } func (h *ConnectHandler) ListUsers(ctx context.Context, request *connect.Request[frontierv1beta1.ListUsersRequest]) (*connect.Response[frontierv1beta1.ListUsersResponse], error) { - errorLogger := NewErrorLogger() auditor := audit.GetAuditor(ctx, request.Msg.GetOrgId()) var users []*frontierv1beta1.User @@ -594,17 +544,13 @@ func (h *ConnectHandler) ListUsers(ctx context.Context, request *connect.Request }) } if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListUsers", err, - "org_id", request.Msg.GetOrgId(), - "group_id", request.Msg.GetGroupId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUsers: org_id=%s group_id=%s: %w", request.Msg.GetOrgId(), request.Msg.GetGroupId(), err)) } for _, user := range usersList { userPB, err := transformUserToPB(user) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListUsers", user.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListUsers: entity_id=%s: %w", user.ID, err)) } users = append(users, userPB) } @@ -661,8 +607,7 @@ func (h *ConnectHandler) ExportUsers(ctx context.Context, request *connect.Reque errorLogger.LogServiceError(ctx, request, "ExportUsers.Export", err) return connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("no data to export: %v", err)) } - errorLogger.LogUnexpectedError(ctx, request, "ExportUsers", err) - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("ExportUsers: %w", err)) } return streamBytesInChunks(userDataBytes, contentType, stream) @@ -688,15 +633,13 @@ func (h *ConnectHandler) SearchUsers(ctx context.Context, request *connect.Reque errorLogger.LogServiceError(ctx, request, "SearchUsers.Search", err) return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogUnexpectedError(ctx, request, "SearchUsers", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchUsers: %w", err)) } for _, v := range userData.Users { transformedUser, err := transformUserToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "SearchUsers", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchUsers: entity_id=%s: %w", v.ID, err)) } users = append(users, transformedUser) } @@ -731,17 +674,14 @@ func (h *ConnectHandler) ListOrganizationsByUser(ctx context.Context, request *c State: organization.State(request.Msg.GetState()), }) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListOrganizationsByUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByUser: user_id=%s: %w", userID, err)) } var orgs []*frontierv1beta1.Organization for _, v := range orgList { orgPB, err := transformOrgToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationsByUser", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByUser: entity_id=%s: %w", v.ID, err)) } orgs = append(orgs, orgPB) } @@ -756,9 +696,7 @@ func (h *ConnectHandler) ListOrganizationsByUser(ctx context.Context, request *c case errors.Is(err, user.ErrNotExist), errors.Is(err, user.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrUserNotExist) default: - errorLogger.LogUnexpectedError(ctx, request, "ListOrganizationsByUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByUser: user_id=%s: %w", userID, err)) } } @@ -767,7 +705,7 @@ func (h *ConnectHandler) ListOrganizationsByUser(ctx context.Context, request *c "user_id", userID, ) if err != nil { - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByUser: %w", err)) } return connect.NewResponse(&frontierv1beta1.ListOrganizationsByUserResponse{ @@ -789,18 +727,14 @@ func (h *ConnectHandler) ListOrganizationsByCurrentUser(ctx context.Context, req State: organization.State(request.Msg.GetState()), }) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListOrganizationsByCurrentUser", err, - "principal_id", principal.ID, - "principal_type", principal.Type) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByCurrentUser: principal_id=%s principal_type=%s: %w", principal.ID, principal.Type, err)) } var orgs []*frontierv1beta1.Organization for _, v := range orgList { orgPB, err := transformOrgToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListOrganizationsByCurrentUser", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByCurrentUser: entity_id=%s: %w", v.ID, err)) } orgs = append(orgs, orgPB) } @@ -814,7 +748,7 @@ func (h *ConnectHandler) ListOrganizationsByCurrentUser(ctx context.Context, req "principal_type", principal.Type, ) if err != nil { - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListOrganizationsByCurrentUser: %w", err)) } } @@ -883,9 +817,7 @@ func (h *ConnectHandler) ListProjectsByUser(ctx context.Context, request *connec case errors.Is(err, user.ErrNotExist): return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) default: - errorLogger.LogUnexpectedError(ctx, request, "ListProjectsByUser", err, - "user_id", userID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectsByUser: user_id=%s: %w", userID, err)) } } @@ -893,8 +825,7 @@ func (h *ConnectHandler) ListProjectsByUser(ctx context.Context, request *connec for _, v := range projList { projPB, err := transformProjectToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectsByUser", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectsByUser: entity_id=%s: %w", v.ID, err)) } projects = append(projects, projPB) } @@ -905,8 +836,6 @@ func (h *ConnectHandler) ListProjectsByUser(ctx context.Context, request *connec } func (h *ConnectHandler) ListProjectsByCurrentUser(ctx context.Context, request *connect.Request[frontierv1beta1.ListProjectsByCurrentUserRequest]) (*connect.Response[frontierv1beta1.ListProjectsByCurrentUserResponse], error) { - errorLogger := NewErrorLogger() - principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { return nil, err @@ -921,11 +850,7 @@ func (h *ConnectHandler) ListProjectsByCurrentUser(ctx context.Context, request Pagination: paginate, }) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListProjectsByCurrentUser", err, - "principal_id", principal.ID, - "principal_type", principal.Type, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectsByCurrentUser: principal_id=%s principal_type=%s org_id=%s: %w", principal.ID, principal.Type, request.Msg.GetOrgId(), err)) } var projects []*frontierv1beta1.Project @@ -933,8 +858,7 @@ func (h *ConnectHandler) ListProjectsByCurrentUser(ctx context.Context, request for _, v := range projList { projPB, err := transformProjectToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListProjectsByCurrentUser", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectsByCurrentUser: entity_id=%s: %w", v.ID, err)) } projects = append(projects, projPB) } @@ -945,11 +869,7 @@ func (h *ConnectHandler) ListProjectsByCurrentUser(ctx context.Context, request }) successCheckPairs, err := h.fetchAccessPairsOnResource(ctx, schema.ProjectNamespace, resourceIds, request.Msg.GetWithPermissions()) if err != nil { - errorLogger.LogUnexpectedError(ctx, request, "ListProjectsByCurrentUser", err, - "principal_id", principal.ID, - "principal_type", principal.Type, - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListProjectsByCurrentUser: principal_id=%s principal_type=%s org_id=%s: %w", principal.ID, principal.Type, request.Msg.GetOrgId(), err)) } // Group permissions by project id, emit one access pair per project in // first-seen order. successCheckPairs is unique by (resID, permName) so diff --git a/internal/api/v1beta1connect/user_orgs.go b/internal/api/v1beta1connect/user_orgs.go index 7e5be3645..4923baee7 100644 --- a/internal/api/v1beta1connect/user_orgs.go +++ b/internal/api/v1beta1connect/user_orgs.go @@ -39,9 +39,7 @@ func (h *ConnectHandler) SearchUserOrganizations(ctx context.Context, request *c "user_id", request.Msg.GetId()) return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogUnexpectedError(ctx, request, "SearchUserOrganizations", err, - "user_id", request.Msg.GetId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchUserOrganizations: user_id=%s: %w", request.Msg.GetId(), err)) } for _, v := range userOrgsData.Organizations { diff --git a/internal/api/v1beta1connect/user_pat.go b/internal/api/v1beta1connect/user_pat.go index ed244364f..8ee157ebf 100644 --- a/internal/api/v1beta1connect/user_pat.go +++ b/internal/api/v1beta1connect/user_pat.go @@ -54,7 +54,7 @@ func mapPATError(err error) *connect.Error { errors.Is(err, paterrors.ErrExpiryExceeded): return connect.NewError(connect.CodeInvalidArgument, err) default: - return connect.NewError(connect.CodeInternal, ErrInternalServerError) + return connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", err)) } } @@ -127,8 +127,7 @@ func (h *ConnectHandler) ListRolesForPAT(ctx context.Context, request *connect.R for _, v := range roleList { rolePB, err := transformRoleToPB(v) if err != nil { - errorLogger.LogTransformError(ctx, request, "ListRolesForPAT", v.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListRolesForPAT: entity_id=%s: %w", v.ID, err)) } roles = append(roles, &rolePB) } diff --git a/internal/api/v1beta1connect/user_pat_test.go b/internal/api/v1beta1connect/user_pat_test.go index e0fd18343..a5fd6c66d 100644 --- a/internal/api/v1beta1connect/user_pat_test.go +++ b/internal/api/v1beta1connect/user_pat_test.go @@ -253,7 +253,7 @@ func TestHandler_CreateCurrentUserPAT(t *testing.T) { ExpiresAt: timestamppb.New(testTime), }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("unexpected error"))), }, { name: "should create PAT successfully and return response", @@ -476,7 +476,7 @@ func TestHandler_GetCurrentUserPAT(t *testing.T) { Id: testPATID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("unexpected error"))), }, { name: "should return PAT successfully", @@ -704,7 +704,7 @@ func TestHandler_ListRolesForPAT(t *testing.T) { setup: func(ps *mocks.UserPATService) { ps.EXPECT().ListAllowedRoles(mock.Anything, mock.Anything).Return(nil, errors.New("db error")) }, - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("db error"))), }, { name: "should return roles successfully", @@ -877,7 +877,7 @@ func TestHandler_DeleteCurrentUserPAT(t *testing.T) { request: connect.NewRequest(&frontierv1beta1.DeleteCurrentUserPATRequest{ Id: testPATID, }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("unexpected error"))), }, { name: "should delete PAT successfully", @@ -1067,7 +1067,7 @@ func TestHandler_UpdateCurrentUserPAT(t *testing.T) { Title: "updated-title", Scopes: []*frontierv1beta1.PATScope{{RoleId: testRoleID, ResourceType: "app/organization"}}, }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("unexpected error"))), }, { name: "should update PAT successfully", @@ -1255,7 +1255,7 @@ func TestHandler_RegenerateCurrentUserPAT(t *testing.T) { Id: testPATID, ExpiresAt: timestamppb.New(futureExpiry), }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("unexpected error"))), }, { name: "should regenerate PAT successfully", @@ -1424,7 +1424,7 @@ func TestHandler_SearchCurrentUserPATs(t *testing.T) { request: connect.NewRequest(&frontierv1beta1.SearchCurrentUserPATsRequest{ OrgId: testOrgID, }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("db error"))), }, } @@ -1533,7 +1533,7 @@ func TestHandler_CheckCurrentUserPATTitle(t *testing.T) { OrgId: testOrgID, Title: "my-token", }), - wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("mapPATError: %w", errors.New("db error"))), }, { name: "should return available true when title is free", diff --git a/internal/api/v1beta1connect/user_projects.go b/internal/api/v1beta1connect/user_projects.go index 604193a8b..f4850b43b 100644 --- a/internal/api/v1beta1connect/user_projects.go +++ b/internal/api/v1beta1connect/user_projects.go @@ -48,10 +48,7 @@ func (h *ConnectHandler) SearchUserProjects(ctx context.Context, request *connec "org_id", request.Msg.GetOrgId()) return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogUnexpectedError(ctx, request, "SearchUserProjects", err, - "user_id", request.Msg.GetUserId(), - "org_id", request.Msg.GetOrgId()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchUserProjects: user_id=%s org_id=%s: %w", request.Msg.GetUserId(), request.Msg.GetOrgId(), err)) } for _, v := range userProjectsData.Projects { diff --git a/internal/api/v1beta1connect/user_test.go b/internal/api/v1beta1connect/user_test.go index 94a0437f9..c6cf10c30 100644 --- a/internal/api/v1beta1connect/user_test.go +++ b/internal/api/v1beta1connect/user_test.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "testing" "time" @@ -67,7 +68,7 @@ func TestConnectHandler_ListUsers(t *testing.T) { Keyword: "", }), want: nil, - err: connect.NewError(connect.CodeInternal, ErrInternalServerError), + err: connect.NewError(connect.CodeInternal, fmt.Errorf("ListUsers: org_id=%s group_id=%s: %w", "", "", errors.New("test error"))), }, { title: "should return all users if user service return all users", setup: func(us *mocks.UserService) { diff --git a/internal/api/v1beta1connect/v1beta1connect.go b/internal/api/v1beta1connect/v1beta1connect.go index b3d3d4b8b..107ce0b29 100644 --- a/internal/api/v1beta1connect/v1beta1connect.go +++ b/internal/api/v1beta1connect/v1beta1connect.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/billing/checkout" @@ -137,14 +138,14 @@ func (h *ConnectHandler) GetOrgIDFromSubscriptionID(ctx context.Context, subscri if errors.Is(err, subscription.ErrInvalidUUID) || errors.Is(err, subscription.ErrInvalidID) { return "", connect.NewError(connect.CodeInvalidArgument, err) } - return "", connect.NewError(connect.CodeInternal, ErrInternalServerError) + return "", connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrgIDFromSubscriptionID: %w", err)) } cust, err := h.customerService.GetByID(ctx, sub.CustomerID) if err != nil { if errors.Is(err, customer.ErrNotFound) { return "", connect.NewError(connect.CodeNotFound, ErrNotFound) } - return "", connect.NewError(connect.CodeInternal, ErrInternalServerError) + return "", connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrgIDFromSubscriptionID: %w", err)) } return cust.OrgID, nil } @@ -159,14 +160,14 @@ func (h *ConnectHandler) GetOrgIDFromCheckoutID(ctx context.Context, checkoutID if errors.Is(err, checkout.ErrInvalidUUID) || errors.Is(err, checkout.ErrInvalidID) { return "", connect.NewError(connect.CodeInvalidArgument, err) } - return "", connect.NewError(connect.CodeInternal, ErrInternalServerError) + return "", connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrgIDFromCheckoutID: %w", err)) } cust, err := h.customerService.GetByID(ctx, co.CustomerID) if err != nil { if errors.Is(err, customer.ErrNotFound) { return "", connect.NewError(connect.CodeNotFound, ErrNotFound) } - return "", connect.NewError(connect.CodeInternal, ErrInternalServerError) + return "", connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrgIDFromCheckoutID: %w", err)) } return cust.OrgID, nil } @@ -181,7 +182,7 @@ func (h *ConnectHandler) GetOrgIDFromBillingAccountID(ctx context.Context, billi if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return "", connect.NewError(connect.CodeInvalidArgument, err) } - return "", connect.NewError(connect.CodeInternal, ErrInternalServerError) + return "", connect.NewError(connect.CodeInternal, fmt.Errorf("GetOrgIDFromBillingAccountID: %w", err)) } return cust.OrgID, nil } diff --git a/internal/api/v1beta1connect/webhook.go b/internal/api/v1beta1connect/webhook.go index 58fe39de5..eced182f0 100644 --- a/internal/api/v1beta1connect/webhook.go +++ b/internal/api/v1beta1connect/webhook.go @@ -2,6 +2,7 @@ package v1beta1connect import ( "context" + "fmt" "connectrpc.com/connect" "github.com/raystack/frontier/core/webhook" @@ -11,8 +12,6 @@ import ( ) func (h *ConnectHandler) CreateWebhook(ctx context.Context, req *connect.Request[frontierv1beta1.CreateWebhookRequest]) (*connect.Response[frontierv1beta1.CreateWebhookResponse], error) { - errorLogger := NewErrorLogger() - var metaDataMap metadata.Metadata if req.Msg.GetBody().GetMetadata() != nil { metaDataMap = metadata.Build(req.Msg.GetBody().GetMetadata().AsMap()) @@ -26,14 +25,11 @@ func (h *ConnectHandler) CreateWebhook(ctx context.Context, req *connect.Request Metadata: metaDataMap, }) if err != nil { - errorLogger.LogUnexpectedError(ctx, req, "CreateWebhook", err, - "url", req.Msg.GetBody().GetUrl()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateWebhook: url=%s: %w", req.Msg.GetBody().GetUrl(), err)) } endpointPb, err := toProtoWebhookEndpoint(endpoint) if err != nil { - errorLogger.LogTransformError(ctx, req, "CreateWebhook", endpoint.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateWebhook: entity_id=%s: %w", endpoint.ID, err)) } return connect.NewResponse(&frontierv1beta1.CreateWebhookResponse{ Webhook: endpointPb, @@ -41,7 +37,6 @@ func (h *ConnectHandler) CreateWebhook(ctx context.Context, req *connect.Request } func (h *ConnectHandler) UpdateWebhook(ctx context.Context, req *connect.Request[frontierv1beta1.UpdateWebhookRequest]) (*connect.Response[frontierv1beta1.UpdateWebhookResponse], error) { - errorLogger := NewErrorLogger() webhookID := req.Msg.GetId() var metaDataMap metadata.Metadata @@ -58,15 +53,11 @@ func (h *ConnectHandler) UpdateWebhook(ctx context.Context, req *connect.Request Metadata: metaDataMap, }) if err != nil { - errorLogger.LogUnexpectedError(ctx, req, "UpdateWebhook", err, - "webhook_id", webhookID, - "url", req.Msg.GetBody().GetUrl()) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateWebhook: webhook_id=%s url=%s: %w", webhookID, req.Msg.GetBody().GetUrl(), err)) } endpointPb, err := toProtoWebhookEndpoint(endpoint) if err != nil { - errorLogger.LogTransformError(ctx, req, "UpdateWebhook", endpoint.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateWebhook: entity_id=%s: %w", endpoint.ID, err)) } return connect.NewResponse(&frontierv1beta1.UpdateWebhookResponse{ Webhook: endpointPb, @@ -74,20 +65,16 @@ func (h *ConnectHandler) UpdateWebhook(ctx context.Context, req *connect.Request } func (h *ConnectHandler) ListWebhooks(ctx context.Context, req *connect.Request[frontierv1beta1.ListWebhooksRequest]) (*connect.Response[frontierv1beta1.ListWebhooksResponse], error) { - errorLogger := NewErrorLogger() - filter := webhook.EndpointFilter{} endpoints, err := h.webhookService.ListEndpoints(ctx, filter) if err != nil { - errorLogger.LogUnexpectedError(ctx, req, "ListWebhooks", err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListWebhooks: %w", err)) } var webhooks []*frontierv1beta1.Webhook for _, endpoint := range endpoints { endpointPb, err := toProtoWebhookEndpoint(endpoint) if err != nil { - errorLogger.LogTransformError(ctx, req, "ListWebhooks", endpoint.ID, err) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListWebhooks: entity_id=%s: %w", endpoint.ID, err)) } webhooks = append(webhooks, endpointPb) } @@ -97,14 +84,11 @@ func (h *ConnectHandler) ListWebhooks(ctx context.Context, req *connect.Request[ } func (h *ConnectHandler) DeleteWebhook(ctx context.Context, req *connect.Request[frontierv1beta1.DeleteWebhookRequest]) (*connect.Response[frontierv1beta1.DeleteWebhookResponse], error) { - errorLogger := NewErrorLogger() webhookID := req.Msg.GetId() err := h.webhookService.DeleteEndpoint(ctx, webhookID) if err != nil { - errorLogger.LogUnexpectedError(ctx, req, "DeleteWebhook", err, - "webhook_id", webhookID) - return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("DeleteWebhook: webhook_id=%s: %w", webhookID, err)) } return connect.NewResponse(&frontierv1beta1.DeleteWebhookResponse{}), nil } From 5cb59a3cbcfa1afe65eac8adf3d05452e880c732 Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Tue, 9 Jun 2026 01:57:12 +0530 Subject: [PATCH 2/7] fix(api): fix gofmt and whitespace lint issues --- internal/api/v1beta1connect/group.go | 1 - internal/api/v1beta1connect/resource_test.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/api/v1beta1connect/group.go b/internal/api/v1beta1connect/group.go index adb0913db..9dc664e82 100644 --- a/internal/api/v1beta1connect/group.go +++ b/internal/api/v1beta1connect/group.go @@ -349,7 +349,6 @@ func (h *ConnectHandler) RemoveGroupUser(ctx context.Context, request *connect.R } if err := h.membershipService.RemoveGroupMember(ctx, request.Msg.GetId(), request.Msg.GetUserId(), schema.UserPrincipal); err != nil { - switch { case errors.Is(err, group.ErrNotExist), errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID): return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound) diff --git a/internal/api/v1beta1connect/resource_test.go b/internal/api/v1beta1connect/resource_test.go index b3975e0d1..462c869eb 100644 --- a/internal/api/v1beta1connect/resource_test.go +++ b/internal/api/v1beta1connect/resource_test.go @@ -473,7 +473,7 @@ func TestConnectHandler_GetProjectResource(t *testing.T) { } rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), testResource.ID).Return(invalidResource, nil) }, - request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{ + request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{ Id: testResource.ID, }), want: nil, From 8b24fbc271e343d9bd70237a33273b20c5436627 Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Tue, 9 Jun 2026 11:00:01 +0530 Subject: [PATCH 3/7] =?UTF-8?q?fix(api):=20address=20review=20=E2=80=94=20?= =?UTF-8?q?fix=20metadata=20error=20code,=20pass=20through=20principal=20e?= =?UTF-8?q?rrors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/api/v1beta1connect/billing_invoice_test.go | 4 ++-- internal/api/v1beta1connect/billing_plan_test.go | 4 ++-- internal/api/v1beta1connect/group_test.go | 6 +++--- internal/api/v1beta1connect/prospect.go | 2 +- internal/api/v1beta1connect/user.go | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/api/v1beta1connect/billing_invoice_test.go b/internal/api/v1beta1connect/billing_invoice_test.go index 0f5261102..da107cb50 100644 --- a/internal/api/v1beta1connect/billing_invoice_test.go +++ b/internal/api/v1beta1connect/billing_invoice_test.go @@ -274,7 +274,7 @@ func TestConnectHandler_ListInvoices(t *testing.T) { NonzeroAmountOnly: false, }), want: nil, - wantErr: errors.New("proto: invalid type: chan int"), + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } @@ -490,7 +490,7 @@ func TestConnectHandler_GetUpcomingInvoice(t *testing.T) { OrgId: "org-123", }), want: nil, - wantErr: errors.New("proto: invalid type: chan int"), + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } diff --git a/internal/api/v1beta1connect/billing_plan_test.go b/internal/api/v1beta1connect/billing_plan_test.go index 2cb59654e..29b7b2c4a 100644 --- a/internal/api/v1beta1connect/billing_plan_test.go +++ b/internal/api/v1beta1connect/billing_plan_test.go @@ -462,7 +462,7 @@ func TestConnectHandler_ListPlans(t *testing.T) { }, }, nil) }, - wantErr: errors.New("proto: invalid type: chan int"), + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } @@ -563,7 +563,7 @@ func TestConnectHandler_GetPlan(t *testing.T) { Metadata: metadata.Metadata{"invalid": make(chan int)}, // This will cause ToStructPB to fail }, nil) }, - wantErr: errors.New("proto: invalid type: chan int"), + wantErr: errors.New("proto: invalid type: chan int"), errCode: connect.CodeInternal, }, } diff --git a/internal/api/v1beta1connect/group_test.go b/internal/api/v1beta1connect/group_test.go index 8d3036861..e849b71f3 100644 --- a/internal/api/v1beta1connect/group_test.go +++ b/internal/api/v1beta1connect/group_test.go @@ -198,7 +198,7 @@ func TestHandler_ListGroups(t *testing.T) { OrgId: "some-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}"))), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}"))), }, } for _, tt := range tests { @@ -580,7 +580,7 @@ func TestConnectHandler_GetGroup(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: fmt.Errorf("GetGroup: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}")), + wantErrMsg: fmt.Errorf("GetGroup: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}")), }, } for _, tt := range tests { @@ -1086,7 +1086,7 @@ func TestConnectHandler_ListGroupUsers(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]string"))), + wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]string"))), }, { name: "should return success if list group users and group service return nil error", diff --git a/internal/api/v1beta1connect/prospect.go b/internal/api/v1beta1connect/prospect.go index d69a52fae..4563b8cb3 100644 --- a/internal/api/v1beta1connect/prospect.go +++ b/internal/api/v1beta1connect/prospect.go @@ -213,7 +213,7 @@ func (h *ConnectHandler) UpdateProspect(ctx context.Context, request *connect.Re subsStatus := frontierv1beta1.Prospect_Status_name[int32(reqStatus)] // convert using proto methods metaDataMap, err := buildAndValidateMetadata(request.Msg.GetMetadata().AsMap(), h) if err != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("UpdateProspect: %w", err)) + return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadBodyMetaSchemaError) } updatedProspect, err := h.prospectService.Update(ctx, prospect.Prospect{ ID: prospectId, diff --git a/internal/api/v1beta1connect/user.go b/internal/api/v1beta1connect/user.go index 2b696e6b4..94d281d37 100644 --- a/internal/api/v1beta1connect/user.go +++ b/internal/api/v1beta1connect/user.go @@ -68,7 +68,7 @@ func (h *ConnectHandler) ListAllUsers(ctx context.Context, request *connect.Requ func (h *ConnectHandler) GetCurrentAdminUser(ctx context.Context, request *connect.Request[frontierv1beta1.GetCurrentAdminUserRequest]) (*connect.Response[frontierv1beta1.GetCurrentAdminUserResponse], error) { principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentAdminUser: %w", err)) + return nil, err } if principal.Type == schema.ServiceUserPrincipal { @@ -188,7 +188,7 @@ func (h *ConnectHandler) GetUser(ctx context.Context, request *connect.Request[f func (h *ConnectHandler) GetCurrentUser(ctx context.Context, request *connect.Request[frontierv1beta1.GetCurrentUserRequest]) (*connect.Response[frontierv1beta1.GetCurrentUserResponse], error) { principal, err := h.GetLoggedInPrincipal(ctx) if err != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetCurrentUser: %w", err)) + return nil, err } if principal.Type == schema.ServiceUserPrincipal { From 5ff4ebc25993a97f6e9481bc0be9b81e7a268248 Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Tue, 9 Jun 2026 11:04:02 +0530 Subject: [PATCH 4/7] fix(api): remove leftover errorLogger calls in billing_invoice.go --- internal/api/v1beta1connect/billing_invoice.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/internal/api/v1beta1connect/billing_invoice.go b/internal/api/v1beta1connect/billing_invoice.go index d43c98685..58aa319c0 100644 --- a/internal/api/v1beta1connect/billing_invoice.go +++ b/internal/api/v1beta1connect/billing_invoice.go @@ -40,7 +40,6 @@ func (h *ConnectHandler) ListAllInvoices(ctx context.Context, request *connect.R } func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.ListInvoicesRequest]) (*connect.Response[frontierv1beta1.ListInvoicesResponse], error) { - errorLogger := NewErrorLogger() // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) @@ -55,8 +54,6 @@ func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Requ if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "ListInvoices.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("ListInvoices.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID @@ -88,7 +85,6 @@ func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Requ } func (h *ConnectHandler) GetUpcomingInvoice(ctx context.Context, request *connect.Request[frontierv1beta1.GetUpcomingInvoiceRequest]) (*connect.Response[frontierv1beta1.GetUpcomingInvoiceResponse], error) { - errorLogger := NewErrorLogger() // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) @@ -103,8 +99,6 @@ func (h *ConnectHandler) GetUpcomingInvoice(ctx context.Context, request *connec if errors.Is(err, customer.ErrInvalidUUID) || errors.Is(err, customer.ErrInvalidID) { return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest) } - errorLogger.LogServiceError(ctx, request, "GetUpcomingInvoice.GetByOrgID", err, - "org_id", request.Msg.GetOrgId()) return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetUpcomingInvoice.GetByOrgID: org_id=%s: %w", request.Msg.GetOrgId(), err)) } billingID := cust.ID @@ -166,7 +160,6 @@ func (h *ConnectHandler) GenerateInvoices(ctx context.Context, request *connect. } func (h *ConnectHandler) SearchInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.SearchInvoicesRequest]) (*connect.Response[frontierv1beta1.SearchInvoicesResponse], error) { - errorLogger := NewErrorLogger() var invoices []*frontierv1beta1.SearchInvoicesResponse_Invoice @@ -185,9 +178,6 @@ func (h *ConnectHandler) SearchInvoices(ctx context.Context, request *connect.Re if errors.Is(err, invoice.ErrBadInput) { return nil, connect.NewError(connect.CodeInvalidArgument, err) } - errorLogger.LogServiceError(ctx, request, "SearchInvoices.SearchInvoices", err, - "query_offset", rqlQuery.Offset, - "query_limit", rqlQuery.Limit) return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("SearchInvoices.SearchInvoices: query_offset=%d query_limit=%d: %w", rqlQuery.Offset, rqlQuery.Limit, err)) } From b6880c0d6f6be9cbe5c19ec00fb580ba987a87f8 Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Tue, 9 Jun 2026 11:16:31 +0530 Subject: [PATCH 5/7] fix(api): remove remaining duplicate errorLogger calls in billing handlers --- internal/api/v1beta1connect/billing_checkout.go | 4 ---- internal/api/v1beta1connect/billing_customer.go | 8 -------- 2 files changed, 12 deletions(-) diff --git a/internal/api/v1beta1connect/billing_checkout.go b/internal/api/v1beta1connect/billing_checkout.go index 6dd1f9b56..07f282298 100644 --- a/internal/api/v1beta1connect/billing_checkout.go +++ b/internal/api/v1beta1connect/billing_checkout.go @@ -13,8 +13,6 @@ import ( ) func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Request[frontierv1beta1.CreateCheckoutRequest]) (*connect.Response[frontierv1beta1.CreateCheckoutResponse], error) { - errorLogger := NewErrorLogger() - // Always infer billing_id from org_id (ignore billing_id from request for security) billingID, err := h.GetBillingAccountFromOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -48,8 +46,6 @@ func (h *ConnectHandler) CreateCheckout(ctx context.Context, request *connect.Re if errors.Is(err, checkout.ErrKycCompleted) { return nil, connect.NewError(connect.CodeFailedPrecondition, ErrPortalChangesKycCompleted) } - errorLogger.LogServiceError(ctx, request, "CreateCheckout.CreateSessionForCustomerPortal", err, - "billing_id", billingID) return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("CreateCheckout.CreateSessionForCustomerPortal: billing_id=%s: %w", billingID, err)) } diff --git a/internal/api/v1beta1connect/billing_customer.go b/internal/api/v1beta1connect/billing_customer.go index 0aa56e58f..76352a93d 100644 --- a/internal/api/v1beta1connect/billing_customer.go +++ b/internal/api/v1beta1connect/billing_customer.go @@ -119,15 +119,11 @@ func (h *ConnectHandler) UpdateBillingAccount(ctx context.Context, request *conn } func (h *ConnectHandler) RegisterBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.RegisterBillingAccountRequest]) (*connect.Response[frontierv1beta1.RegisterBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - _, err := h.customerService.RegisterToProviderIfRequired(ctx, request.Msg.GetId()) if err != nil { if errors.Is(err, customer.ErrNotFound) { return nil, connect.NewError(connect.CodeNotFound, ErrCustomerNotFound) } - errorLogger.LogServiceError(ctx, request, "RegisterBillingAccount.RegisterToProviderIfRequired", err, - "customer_id", request.Msg.GetId()) return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("RegisterBillingAccount.RegisterToProviderIfRequired: customer_id=%s: %w", request.Msg.GetId(), err)) } return connect.NewResponse(&frontierv1beta1.RegisterBillingAccountResponse{}), nil @@ -288,15 +284,11 @@ func (h *ConnectHandler) GetBillingAccountDetails(ctx context.Context, request * } func (h *ConnectHandler) GetBillingAccount(ctx context.Context, request *connect.Request[frontierv1beta1.GetBillingAccountRequest]) (*connect.Response[frontierv1beta1.GetBillingAccountResponse], error) { - errorLogger := NewErrorLogger() - customerOb, err := h.customerService.GetByID(ctx, request.Msg.GetId()) if err != nil { if errors.Is(err, customer.ErrNotFound) { return nil, connect.NewError(connect.CodeNotFound, ErrNotFound) } - errorLogger.LogServiceError(ctx, request, "GetBillingAccount.GetByID", err, - "customer_id", request.Msg.GetId()) return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("GetBillingAccount.GetByID: customer_id=%s: %w", request.Msg.GetId(), err)) } From 715c7c7b6c8834b7f0db1e1727209f72c7599f2e Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Tue, 9 Jun 2026 12:31:02 +0530 Subject: [PATCH 6/7] fix(api): remove unnecessary leading newlines in billing_invoice.go --- internal/api/v1beta1connect/billing_invoice.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/api/v1beta1connect/billing_invoice.go b/internal/api/v1beta1connect/billing_invoice.go index 58aa319c0..16268d7df 100644 --- a/internal/api/v1beta1connect/billing_invoice.go +++ b/internal/api/v1beta1connect/billing_invoice.go @@ -40,7 +40,6 @@ func (h *ConnectHandler) ListAllInvoices(ctx context.Context, request *connect.R } func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.ListInvoicesRequest]) (*connect.Response[frontierv1beta1.ListInvoicesResponse], error) { - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -85,7 +84,6 @@ func (h *ConnectHandler) ListInvoices(ctx context.Context, request *connect.Requ } func (h *ConnectHandler) GetUpcomingInvoice(ctx context.Context, request *connect.Request[frontierv1beta1.GetUpcomingInvoiceRequest]) (*connect.Response[frontierv1beta1.GetUpcomingInvoiceResponse], error) { - // Always infer billing_id from org_id cust, err := h.customerService.GetByOrgID(ctx, request.Msg.GetOrgId()) if err != nil { @@ -160,7 +158,6 @@ func (h *ConnectHandler) GenerateInvoices(ctx context.Context, request *connect. } func (h *ConnectHandler) SearchInvoices(ctx context.Context, request *connect.Request[frontierv1beta1.SearchInvoicesRequest]) (*connect.Response[frontierv1beta1.SearchInvoicesResponse], error) { - var invoices []*frontierv1beta1.SearchInvoicesResponse_Invoice rqlQuery, err := utils.TransformProtoToRQL(request.Msg.GetQuery(), invoice.InvoiceWithOrganization{}) From a79312579ab07d368cc9fd40dd532fbff78d5045 Mon Sep 17 00:00:00 2001 From: Rohil Surana Date: Tue, 9 Jun 2026 13:10:25 +0530 Subject: [PATCH 7/7] fix(api): use code-only assertions for proto transform errors in tests --- .../api/v1beta1connect/billing_plan_test.go | 4 +-- internal/api/v1beta1connect/group_test.go | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/api/v1beta1connect/billing_plan_test.go b/internal/api/v1beta1connect/billing_plan_test.go index 29b7b2c4a..205cab1c2 100644 --- a/internal/api/v1beta1connect/billing_plan_test.go +++ b/internal/api/v1beta1connect/billing_plan_test.go @@ -462,7 +462,7 @@ func TestConnectHandler_ListPlans(t *testing.T) { }, }, nil) }, - wantErr: errors.New("proto: invalid type: chan int"), + wantErr: errors.New("invalid type: chan int"), errCode: connect.CodeInternal, }, } @@ -563,7 +563,7 @@ func TestConnectHandler_GetPlan(t *testing.T) { Metadata: metadata.Metadata{"invalid": make(chan int)}, // This will cause ToStructPB to fail }, nil) }, - wantErr: errors.New("proto: invalid type: chan int"), + wantErr: errors.New("invalid type: chan int"), errCode: connect.CodeInternal, }, } diff --git a/internal/api/v1beta1connect/group_test.go b/internal/api/v1beta1connect/group_test.go index e849b71f3..d3beb6876 100644 --- a/internal/api/v1beta1connect/group_test.go +++ b/internal/api/v1beta1connect/group_test.go @@ -198,7 +198,7 @@ func TestHandler_ListGroups(t *testing.T) { OrgId: "some-id", }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroups: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}"))), + wantErr: connect.NewError(connect.CodeInternal, errors.New("proto transform error")), }, } for _, tt := range tests { @@ -213,7 +213,7 @@ func TestHandler_ListGroups(t *testing.T) { got, err := h.ListGroups(context.Background(), tt.request) assert.EqualValues(t, tt.want, got) if tt.want == nil { - assert.ErrorContains(t, err, tt.wantErr.Error()) + assert.Equal(t, connect.CodeOf(err), connect.CodeOf(tt.wantErr)) } }) } @@ -443,7 +443,7 @@ func TestConnectHandler_CreateGroup(t *testing.T) { connectErr := &connect.Error{} assert.True(t, errors.As(err, &connectErr)) assert.Equal(t, tt.wantErrCode, connectErr.Code()) - assert.Equal(t, tt.wantErrMsg.Error(), connectErr.Message()) + assert.Contains(t, connectErr.Message(), tt.wantErrMsg.Error()) assert.Nil(t, got) } else { assert.NoError(t, err) @@ -580,7 +580,7 @@ func TestConnectHandler_GetGroup(t *testing.T) { want: nil, wantErr: true, wantErrCode: connect.CodeInternal, - wantErrMsg: fmt.Errorf("GetGroup: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]interface {}")), + wantErrMsg: errors.New("invalid type"), }, } for _, tt := range tests { @@ -600,7 +600,7 @@ func TestConnectHandler_GetGroup(t *testing.T) { connectErr := &connect.Error{} assert.True(t, errors.As(err, &connectErr)) assert.Equal(t, tt.wantErrCode, connectErr.Code()) - assert.Equal(t, tt.wantErrMsg.Error(), connectErr.Message()) + assert.Contains(t, connectErr.Message(), tt.wantErrMsg.Error()) assert.Nil(t, got) } else { assert.NoError(t, err) @@ -865,7 +865,7 @@ func TestConnectHandler_UpdateGroup(t *testing.T) { connectErr := &connect.Error{} assert.True(t, errors.As(err, &connectErr)) assert.Equal(t, tt.wantErrCode, connectErr.Code()) - assert.Equal(t, tt.wantErrMsg.Error(), connectErr.Message()) + assert.Contains(t, connectErr.Message(), tt.wantErrMsg.Error()) assert.Nil(t, got) } else { assert.NoError(t, err) @@ -1006,7 +1006,7 @@ func TestConnectHandler_ListOrganizationGroups(t *testing.T) { connectErr := &connect.Error{} assert.True(t, errors.As(err, &connectErr)) assert.Equal(t, tt.wantErrCode, connectErr.Code()) - assert.Equal(t, tt.wantErrMsg.Error(), connectErr.Message()) + assert.Contains(t, connectErr.Message(), tt.wantErrMsg.Error()) assert.Nil(t, got) } else { assert.NoError(t, err) @@ -1086,7 +1086,7 @@ func TestConnectHandler_ListGroupUsers(t *testing.T) { OrgId: testOrgID, }), want: nil, - wantErr: connect.NewError(connect.CodeInternal, fmt.Errorf("ListGroupUsers: entity_id=%s: %w", "", errors.New("proto: invalid type: map[int]string"))), + wantErr: connect.NewError(connect.CodeInternal, errors.New("invalid type")), }, { name: "should return success if list group users and group service return nil error", @@ -1228,7 +1228,7 @@ func TestConnectHandler_ListGroupUsers(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + assert.Contains(t, err.(*connect.Error).Message(), tt.wantErr.(*connect.Error).Message()) } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, got) @@ -1416,7 +1416,7 @@ func TestConnectHandler_RemoveGroupUser(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + assert.Contains(t, err.(*connect.Error).Message(), tt.wantErr.(*connect.Error).Message()) } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, got) @@ -1501,7 +1501,7 @@ func TestConnectHandler_EnableGroup(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + assert.Contains(t, err.(*connect.Error).Message(), tt.wantErr.(*connect.Error).Message()) } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, got) @@ -1586,7 +1586,7 @@ func TestConnectHandler_DisableGroup(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + assert.Contains(t, err.(*connect.Error).Message(), tt.wantErr.(*connect.Error).Message()) } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, got) @@ -1671,7 +1671,7 @@ func TestConnectHandler_DeleteGroup(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + assert.Contains(t, err.(*connect.Error).Message(), tt.wantErr.(*connect.Error).Message()) } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, got) @@ -1823,7 +1823,7 @@ func TestConnectHandler_SetGroupMemberRole(t *testing.T) { if tt.wantErr != nil { assert.Error(t, err) assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code()) - assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message()) + assert.Contains(t, err.(*connect.Error).Message(), tt.wantErr.(*connect.Error).Message()) } else { assert.NoError(t, err) assert.EqualValues(t, tt.want, got)