<commit_before>// Copyright © 2017 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package errors

import (
	"fmt"
	"io"
	"strings"

	errs "github.com/pkg/errors"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

type ErrType string

// These constants represent error types
const (
	AlreadyExists    ErrType = "already exists"
	Internal         ErrType = "internal"
	InvalidArgument  ErrType = "invalid argument"
	NotFound         ErrType = "not found"
	OutOfRange       ErrType = "out of range"
	PermissionDenied ErrType = "permission denied"
	Unknown          ErrType = "unknown"
)

// GetErrType returns the type of err
func GetErrType(err error) ErrType {
	switch errs.Cause(err).(type) {
	case *ErrAlreadyExists:
		return AlreadyExists
	case *ErrInternal:
		return Internal
	case *ErrInvalidArgument:
		return InvalidArgument
	case *ErrNotFound:
		return NotFound
	case *ErrPermissionDenied:
		return PermissionDenied
	}
	return Unknown
}

// IsPermissionDenied returns whether error type is PermissionDenied
func IsPermissionDenied(err error) bool {
	return GetErrType(err) == PermissionDenied
}

// IsNotFound returns whether error type is NotFound
func IsNotFound(err error) bool {
	return GetErrType(err) == NotFound
}

// IsInvalidArgument returns whether error type is InvalidArgument
func IsInvalidArgument(err error) bool {
	return GetErrType(err) == InvalidArgument
}

// IsInternal returns whether error type is Internal
func IsInternal(err error) bool {
	return GetErrType(err) == Internal
}

// IsAlreadyExists returns whether error type is AlreadyExists
func IsAlreadyExists(err error) bool {
	return GetErrType(err) == AlreadyExists
}

// BuildGRPCError returns the error with a GRPC code
func BuildGRPCError(err error) error {
	if err == nil {
		return nil
	}
	code := grpc.Code(err)
	if code != codes.Unknown {
		return err // it already is a gRPC error
	}
	switch errs.Cause(err).(type) {
	case *ErrAlreadyExists:
		code = codes.AlreadyExists
	case *ErrInternal:
		code = codes.Internal
	case *ErrInvalidArgument:
		code = codes.InvalidArgument
	case *ErrNotFound:
		code = codes.NotFound
	case *ErrPermissionDenied:
		code = codes.PermissionDenied
	}
	switch err {
	case context.Canceled:
		code = codes.Canceled
	case io.EOF:
		code = codes.OutOfRange
	}
	return grpc.Errorf(code, err.Error())
}

// FromGRPCError creates a regular error with the same type as the gRPC error
func FromGRPCError(err error) error {
	if err == nil {
		return nil
	}
	code := grpc.Code(err)
	desc := grpc.ErrorDesc(err)
	switch code {
	case codes.AlreadyExists:
		return NewErrAlreadyExists(strings.TrimSuffix(desc, " already exists"))
	case codes.Internal:
		return NewErrInternal(strings.TrimPrefix(desc, "Internal error: "))
	case codes.InvalidArgument:
		if split := strings.Split(desc, " not valid: "); len(split) == 2 {
			return NewErrInvalidArgument(split[0], split[1])
		}
		return NewErrInvalidArgument("Argument", desc)
	case codes.NotFound:
		return NewErrNotFound(strings.TrimSuffix(desc, " not found"))
	case codes.PermissionDenied:
		return NewErrPermissionDenied(strings.TrimPrefix(desc, "permission denied: "))
	case codes.Unknown: // This also includes all non-gRPC errors
		if desc == "EOF" {
			return io.EOF
		}
		return errs.New(desc)
	}
	return NewErrInternal(fmt.Sprintf("[%s] %s", code, desc))
}
<commit_msg>Make FromGRPCError return internal error if already converted<commit_after>// Copyright © 2017 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package errors

import (
	"fmt"
	"io"
	"strings"

	errs "github.com/pkg/errors"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

type ErrType string

// These constants represent error types
const (
	AlreadyExists    ErrType = "already exists"
	Internal         ErrType = "internal"
	InvalidArgument  ErrType = "invalid argument"
	NotFound         ErrType = "not found"
	OutOfRange       ErrType = "out of range"
	PermissionDenied ErrType = "permission denied"
	Unknown          ErrType = "unknown"
)

// GetErrType returns the type of err
func GetErrType(err error) ErrType {
	switch errs.Cause(err).(type) {
	case *ErrAlreadyExists:
		return AlreadyExists
	case *ErrInternal:
		return Internal
	case *ErrInvalidArgument:
		return InvalidArgument
	case *ErrNotFound:
		return NotFound
	case *ErrPermissionDenied:
		return PermissionDenied
	}
	return Unknown
}

// IsPermissionDenied returns whether error type is PermissionDenied
func IsPermissionDenied(err error) bool {
	return GetErrType(err) == PermissionDenied
}

// IsNotFound returns whether error type is NotFound
func IsNotFound(err error) bool {
	return GetErrType(err) == NotFound
}

// IsInvalidArgument returns whether error type is InvalidArgument
func IsInvalidArgument(err error) bool {
	return GetErrType(err) == InvalidArgument
}

// IsInternal returns whether error type is Internal
func IsInternal(err error) bool {
	return GetErrType(err) == Internal
}

// IsAlreadyExists returns whether error type is AlreadyExists
func IsAlreadyExists(err error) bool {
	return GetErrType(err) == AlreadyExists
}

// BuildGRPCError returns the error with a GRPC code
func BuildGRPCError(err error) error {
	if err == nil {
		return nil
	}
	code := grpc.Code(err)
	if code != codes.Unknown {
		return err // it already is a gRPC error
	}
	switch errs.Cause(err).(type) {
	case *ErrAlreadyExists:
		code = codes.AlreadyExists
	case *ErrInternal:
		code = codes.Internal
	case *ErrInvalidArgument:
		code = codes.InvalidArgument
	case *ErrNotFound:
		code = codes.NotFound
	case *ErrPermissionDenied:
		code = codes.PermissionDenied
	}
	switch err {
	case context.Canceled:
		code = codes.Canceled
	case io.EOF:
		code = codes.OutOfRange
	}
	return grpc.Errorf(code, err.Error())
}

// FromGRPCError creates a regular error with the same type as the gRPC error
func FromGRPCError(err error) error {
	if err == nil {
		return nil
	}

	if GetErrType(err) != Unknown {
		return err
	}

	code := grpc.Code(err)
	desc := grpc.ErrorDesc(err)
	switch code {
	case codes.AlreadyExists:
		return NewErrAlreadyExists(strings.TrimSuffix(desc, " already exists"))
	case codes.Internal:
		return NewErrInternal(strings.TrimPrefix(desc, "Internal error: "))
	case codes.InvalidArgument:
		if split := strings.Split(desc, " not valid: "); len(split) == 2 {
			return NewErrInvalidArgument(split[0], split[1])
		}
		return NewErrInvalidArgument("Argument", desc)
	case codes.NotFound:
		return NewErrNotFound(strings.TrimSuffix(desc, " not found"))
	case codes.PermissionDenied:
		return NewErrPermissionDenied(strings.TrimPrefix(desc, "permission denied: "))
	case codes.Unknown: // This also includes all non-gRPC errors
		if desc == "EOF" {
			return io.EOF
		}
		return errs.New(desc)
	}
	return NewErrInternal(fmt.Sprintf("[%s] %s", code, desc))
}

{'fraction_non_alphanumeric': 0.09443411074545714, 'fraction_numerical': 0.002003147803691515, 'mean_word_length': 4.295454545454546, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5864267', 'n_tokens_mistral': 2274, 'n_tokens_neox': 2153, 'n_words': 670}