package shared import ( "context" authlogging "galaxy/authsession/internal/logging" "go.uber.org/zap" ) // LogServiceOutcome writes one structured service-level outcome log with a // stable severity derived from err and with trace fields attached when ctx // carries an active span. func LogServiceOutcome(logger *zap.Logger, ctx context.Context, message string, err error, fields ...zap.Field) { if logger == nil { logger = zap.NewNop() } fields = append(fields, authlogging.TraceFieldsFromContext(ctx)...) switch { case err == nil: logger.Info(message, fields...) case isExpectedServiceErrorCode(CodeOf(err)): logger.Warn(message, append(fields, zap.Error(err))...) default: logger.Error(message, append(fields, zap.Error(err))...) } } func isExpectedServiceErrorCode(code string) bool { switch code { case ErrorCodeInvalidRequest, ErrorCodeChallengeNotFound, ErrorCodeChallengeExpired, ErrorCodeInvalidCode, ErrorCodeInvalidClientPublicKey, ErrorCodeBlockedByPolicy, ErrorCodeSessionLimitExceeded, ErrorCodeSessionNotFound, ErrorCodeSubjectNotFound: return true default: return false } }