func ClassifyErrorByType(in error) metrics.ErrorClass {
	switch in.(type) {
	case *shared.BadRequestError:
		return metrics.UserError
	case *shared.EntityNotExistsError:
		return metrics.UserError
	case *shared.EntityAlreadyExistsError:
		return metrics.UserError
	case *shared.EntityDisabledError:
		return metrics.UserError
	case *shared.InternalServiceError:
		return metrics.InternalError
	case *cherami.BadRequestError:
		return metrics.UserError
	case *cherami.EntityNotExistsError:
		return metrics.UserError
	case *cherami.EntityAlreadyExistsError:
		return metrics.UserError
	case *cherami.EntityDisabledError:
		return metrics.UserError
	case *cherami.InternalServiceError:
		return metrics.InternalError
	}
	return metrics.InternalError
}
ClassifyErrorByType gives the metrics error class for any cherami or common error
package common
import (
	"fmt"
	"strings"
	"time"
	"github.com/uber/tchannel-go"
	"github.com/uber-common/bark"
	"github.com/uber/cherami-server/common/metrics"
	"github.com/uber/cherami-thrift/.generated/go/admin"
	"github.com/uber/cherami-thrift/.generated/go/cherami"
	"github.com/uber/cherami-thrift/.generated/go/controller"
	"github.com/uber/cherami-thrift/.generated/go/shared"
)
func IntPtr(v int) *int {
	return &v
}
func TSPtr(v time.Time) *time.Time {
	return &v
}
func Int16Ptr(v int16) *int16 {
	return &v
}
func Int32Ptr(v int32) *int32 {
	return &v
}
func Int64Ptr(v int64) *int64 {
	return &v
}
func Uint32Ptr(v uint32) *uint32 {
	return &v
}
func Uint64Ptr(v uint64) *uint64 {
	return &v
}
func Float64Ptr(v float64) *float64 {
	return &v
}
func BoolPtr(v bool) *bool {
	return &v
}
func StringPtr(v string) *string {
	return &v
}
func CheramiStatusPtr(status cherami.Status) *cherami.Status {
	return &status
}
func CheramiProtocolPtr(protocol cherami.Protocol) *cherami.Protocol {
	return &protocol
}
func CheramiInputHostCommandTypePtr(cmdType cherami.InputHostCommandType) *cherami.InputHostCommandType {
	return &cmdType
}
func CheramiOutputHostCommandTypePtr(cmdType cherami.OutputHostCommandType) *cherami.OutputHostCommandType {
	return &cmdType
}
func CheramiDestinationTypePtr(destType cherami.DestinationType) *cherami.DestinationType {
	return &destType
}
func CheramiDestinationStatusPtr(status cherami.DestinationStatus) *cherami.DestinationStatus {
	return &status
}
func CheramiConsumerGroupStatusPtr(status cherami.ConsumerGroupStatus) *cherami.ConsumerGroupStatus {
	return &status
}
func CheramiConsumerGroupExtentStatusPtr(status shared.ConsumerGroupExtentStatus) *shared.ConsumerGroupExtentStatus {
	return &status
}
func CheramiChecksumOptionPtr(checksumOption cherami.ChecksumOption) *cherami.ChecksumOption {
	return &checksumOption
}
func InternalChecksumOptionPtr(checksumOption shared.ChecksumOption) *shared.ChecksumOption {
	return &checksumOption
}
func MetadataExtentStatusPtr(status shared.ExtentStatus) *shared.ExtentStatus {
	return &status
}
func MetadataExtentReplicaStatusPtr(status shared.ExtentReplicaStatus) *shared.ExtentReplicaStatus {
	return &status
}
func InternalDestinationTypePtr(destType shared.DestinationType) *shared.DestinationType {
	return &destType
}
func InternalDestinationStatusPtr(status shared.DestinationStatus) *shared.DestinationStatus {
	return &status
}
func InternalConsumerGroupStatusPtr(status shared.ConsumerGroupStatus) *shared.ConsumerGroupStatus {
	return &status
}
func InternalConsumerGroupTypePtr(cgType shared.ConsumerGroupType) *shared.ConsumerGroupType {
	return &cgType
}
func InternalExtentReplicaReplicationStatusTypePtr(status shared.ExtentReplicaReplicationStatus) *shared.ExtentReplicaReplicationStatus {
	return &status
}
func MetadataConsumerGroupExtentStatusPtr(status shared.ConsumerGroupExtentStatus) *shared.ConsumerGroupExtentStatus {
	return &status
}
func AdminNotificationTypePtr(notificationType admin.NotificationType) *admin.NotificationType {
	return &notificationType
}
func SKUPtr(sku controller.SKU) *controller.SKU {
	return &sku
}
func RolePtr(role controller.Role) *controller.Role {
	return &role
}
func NodeStatusPtr(status controller.NodeStatus) *controller.NodeStatus {
	return &status
}
func NodeMetricsPtr(nodeMetrics controller.NodeMetrics) *controller.NodeMetrics {
	return &nodeMetrics
}
func DestinationMetricsPtr(dstMetrics controller.DestinationMetrics) *controller.DestinationMetrics {
	return &dstMetrics
}
func DestinationExtentMetricsPtr(dstExtMetrics controller.DestinationExtentMetrics) *controller.DestinationExtentMetrics {
	return &dstExtMetrics
}
func ConsumerGroupMetricsPtr(cgMetrics controller.ConsumerGroupMetrics) *controller.ConsumerGroupMetrics {
	return &cgMetrics
}
func ConsumerGroupExtentMetricsPtr(cgExtMetrics controller.ConsumerGroupExtentMetrics) *controller.ConsumerGroupExtentMetrics {
	return &cgExtMetrics
}
func StoreExtentMetricsPtr(storeExtMetrics controller.StoreExtentMetrics) *controller.StoreExtentMetrics {
	return &storeExtMetrics
}
func checkForWrappedError(l bark.Logger, in error, checkForInternalServiceError bool) {
	eStr := fmt.Sprintf(`%#v %v`, in, in)
	errList := []string{`BadRequestError`, `EntityNotExistsError`, `EntityAlreadyExistsError`, `EntityDisabledError`}
	if checkForInternalServiceError {
		errList = append(errList, `InternalServiceError`)
	}
	for _, s := range errList {
		if strings.Contains(eStr, s) {
			l.WithFields(bark.Fields{
				TagErr:    in,
				`wrapped`: s,
				`eStr`:    eStr,
			}).Error(`Wrapped error`)
		}
	}
}
func ConvertDownstreamErrors(l bark.Logger, in error) (metrics.ErrorClass, error) {
	switch e := in.(type) {
	case *shared.BadRequestError:
		return metrics.UserError, &cherami.BadRequestError{
			Message: e.Message,
		}
	case *shared.EntityNotExistsError:
		return metrics.UserError, &cherami.EntityNotExistsError{
			Message: e.Message,
		}
	case *shared.EntityAlreadyExistsError:
		return metrics.UserError, &cherami.EntityAlreadyExistsError{
			Message: e.Message,
		}
	case *shared.EntityDisabledError:
		return metrics.UserError, &cherami.EntityDisabledError{
			Message: e.Message,
		}
	case *shared.InternalServiceError:
		checkForWrappedError(l, in, false)
		return metrics.InternalError, &cherami.InternalServiceError{
			Message: e.Message,
		}
	case *cherami.BadRequestError:
		return metrics.UserError, in
	case *cherami.EntityNotExistsError:
		return metrics.UserError, in
	case *cherami.EntityAlreadyExistsError:
		return metrics.UserError, in
	case *cherami.EntityDisabledError:
		return metrics.UserError, in
	case *cherami.InternalServiceError:
		checkForWrappedError(l, in, false)
		return metrics.InternalError, in
	case tchannel.SystemError:
		switch {
		case strings.Contains(e.Error(), `EntityNotExistsError`):
			return metrics.UserError, &cherami.EntityNotExistsError{
				Message: e.Error(),
			}
		default:
			checkForWrappedError(l, in, false)
			return metrics.InternalError, &cherami.InternalServiceError{
				Message: e.Error(),
			}
		}
	default:
		checkForWrappedError(l, in, true  )  
		return metrics.InternalError, &cherami.InternalServiceError{
			Message: e.Error(),
		}
	}
}