github.com/erda-project/erda-infra@v1.0.9/providers/legacy/httpendpoints/errorresp/errors.go (about)

     1  // Copyright (c) 2021 Terminus, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package errorresp
    16  
    17  import (
    18  	"strings"
    19  
    20  	"github.com/erda-project/erda-infra/providers/legacy/httpendpoints/i18n"
    21  )
    22  
    23  // MetaMessage .
    24  type MetaMessage struct {
    25  	Key     string
    26  	Args    []interface{}
    27  	Default string
    28  }
    29  
    30  // APIError .
    31  type APIError struct {
    32  	httpCode           int
    33  	code               string
    34  	msg                string
    35  	localeMetaMessages []MetaMessage
    36  }
    37  
    38  // Error .
    39  func (e *APIError) Error() string {
    40  	if e.msg == "" {
    41  		e.Render(i18n.NewNopLocaleResource())
    42  	}
    43  	return e.msg
    44  }
    45  
    46  // Code .
    47  func (e *APIError) Code() string {
    48  	return e.code
    49  }
    50  
    51  // HTTPCode ...
    52  func (e *APIError) HTTPCode() int {
    53  	return e.httpCode
    54  }
    55  
    56  // Option 可选参数
    57  type Option func(*APIError)
    58  
    59  // New .
    60  func New(options ...Option) *APIError {
    61  	e := &APIError{}
    62  	for _, op := range options {
    63  		op(e)
    64  	}
    65  	return e
    66  }
    67  
    68  // WithMessage .
    69  func WithMessage(msg string) Option {
    70  	return func(a *APIError) {
    71  		a.msg = msg
    72  	}
    73  }
    74  
    75  // WithTemplateMessage .
    76  func WithTemplateMessage(template, defaultValue string, args ...interface{}) Option {
    77  	return func(a *APIError) {
    78  		_ = a.appendMeta(template, defaultValue, args...)
    79  	}
    80  }
    81  
    82  // WithCode .
    83  func WithCode(httpCode int, code string) Option {
    84  	return func(a *APIError) {
    85  		_ = a.appendCode(httpCode, code)
    86  	}
    87  }
    88  
    89  func (e *APIError) appendCode(httpCode int, code string) *APIError {
    90  	e.httpCode = httpCode
    91  	e.code = code
    92  	return e
    93  }
    94  
    95  func (e *APIError) appendMsg(template *i18n.Template, args ...interface{}) *APIError {
    96  	msg := template.Render(args...)
    97  	if e.msg == "" {
    98  		e.msg = msg
    99  		return e
   100  	}
   101  	e.msg = strings.Join([]string{e.msg, ": ", msg}, "")
   102  	return e
   103  }
   104  
   105  func (e *APIError) appendMeta(key string, defaultContent string, args ...interface{}) *APIError {
   106  	e.localeMetaMessages = append(e.localeMetaMessages, MetaMessage{
   107  		Key:     key,
   108  		Args:    args,
   109  		Default: defaultContent,
   110  	})
   111  	return e
   112  }
   113  
   114  func (e *APIError) appendLocaleTemplate(template *i18n.Template, args ...interface{}) *APIError {
   115  	e.localeMetaMessages = append(e.localeMetaMessages, MetaMessage{
   116  		Key:     template.Key(),
   117  		Args:    args,
   118  		Default: template.Content(),
   119  	})
   120  	return e
   121  }
   122  
   123  // Render .
   124  func (e *APIError) Render(localeResource i18n.LocaleResource) string {
   125  	for _, metaMessage := range e.localeMetaMessages {
   126  		var template *i18n.Template
   127  		if !localeResource.ExistKey(metaMessage.Key) && metaMessage.Default != "" {
   128  			template = i18n.NewTemplate(metaMessage.Key, metaMessage.Default)
   129  		} else {
   130  			template = localeResource.GetTemplate(metaMessage.Key)
   131  		}
   132  		msg := template.Render(metaMessage.Args...)
   133  		if e.msg == "" {
   134  			e.msg = msg
   135  		} else {
   136  			e.msg = strings.Join([]string{e.msg, ": ", msg}, "")
   137  		}
   138  	}
   139  	return e.msg
   140  }
   141  
   142  func (e *APIError) dup() *APIError {
   143  	return &APIError{
   144  		httpCode:           e.httpCode,
   145  		code:               e.code,
   146  		msg:                e.msg,
   147  		localeMetaMessages: e.localeMetaMessages,
   148  	}
   149  }