2021-04-18 15:41:13 -04:00
|
|
|
// Copyright (c) 2015-2021 MinIO, Inc.
|
|
|
|
//
|
|
|
|
// This file is part of MinIO Object Storage stack
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2018-05-08 22:04:36 -04:00
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
package config
|
2018-05-08 22:04:36 -04:00
|
|
|
|
|
|
|
import (
|
2019-09-11 13:21:43 -04:00
|
|
|
"errors"
|
2018-05-08 22:04:36 -04:00
|
|
|
"fmt"
|
2020-01-03 10:45:26 -05:00
|
|
|
"net"
|
2019-08-13 00:25:34 -04:00
|
|
|
"syscall"
|
2019-10-04 13:35:33 -04:00
|
|
|
|
2021-06-01 17:59:40 -04:00
|
|
|
"github.com/minio/minio/internal/color"
|
2018-05-08 22:04:36 -04:00
|
|
|
)
|
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
// Err is a structure which contains all information
|
2018-05-08 22:04:36 -04:00
|
|
|
// to print a fatal error message in json or pretty mode
|
2019-10-04 13:35:33 -04:00
|
|
|
// Err implements error so we can use it anywhere
|
|
|
|
type Err struct {
|
2018-05-08 22:04:36 -04:00
|
|
|
msg string
|
|
|
|
detail string
|
|
|
|
action string
|
2019-08-13 00:25:34 -04:00
|
|
|
hint string
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
|
|
|
|
2019-12-26 01:05:54 -05:00
|
|
|
// Clone returns a new Err struct with the same information
|
|
|
|
func (u Err) Clone() Err {
|
|
|
|
return Err{
|
|
|
|
msg: u.msg,
|
|
|
|
detail: u.detail,
|
|
|
|
action: u.action,
|
|
|
|
hint: u.hint,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-18 19:19:29 -04:00
|
|
|
// Error returns the error message
|
2019-10-04 13:35:33 -04:00
|
|
|
func (u Err) Error() string {
|
2018-05-08 22:04:36 -04:00
|
|
|
if u.detail == "" {
|
2019-12-23 19:31:03 -05:00
|
|
|
if u.msg != "" {
|
|
|
|
return u.msg
|
|
|
|
}
|
|
|
|
return "<nil>"
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
|
|
|
return u.detail
|
|
|
|
}
|
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
// Msg - Replace the current error's message
|
|
|
|
func (u Err) Msg(m string, args ...interface{}) Err {
|
2019-12-26 01:05:54 -05:00
|
|
|
e := u.Clone()
|
|
|
|
e.msg = fmt.Sprintf(m, args...)
|
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hint - Replace the current error's message
|
|
|
|
func (u Err) Hint(m string, args ...interface{}) Err {
|
|
|
|
e := u.Clone()
|
|
|
|
e.hint = fmt.Sprintf(m, args...)
|
|
|
|
return e
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
// ErrFn function wrapper
|
|
|
|
type ErrFn func(err error) Err
|
2018-05-08 22:04:36 -04:00
|
|
|
|
|
|
|
// Create a UI error generator, this is needed to simplify
|
|
|
|
// the update of the detailed error message in several places
|
2019-04-09 14:39:42 -04:00
|
|
|
// in MinIO code
|
2019-10-04 13:35:33 -04:00
|
|
|
func newErrFn(msg, action, hint string) ErrFn {
|
|
|
|
return func(err error) Err {
|
|
|
|
u := Err{
|
2018-05-08 22:04:36 -04:00
|
|
|
msg: msg,
|
|
|
|
action: action,
|
2019-08-13 00:25:34 -04:00
|
|
|
hint: hint,
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
u.detail = err.Error()
|
|
|
|
}
|
|
|
|
return u
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
// ErrorToErr inspects the passed error and transforms it
|
2018-05-08 22:04:36 -04:00
|
|
|
// to the appropriate UI error.
|
2019-10-04 13:35:33 -04:00
|
|
|
func ErrorToErr(err error) Err {
|
2019-12-23 19:31:03 -05:00
|
|
|
if err == nil {
|
|
|
|
return Err{}
|
|
|
|
}
|
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
// If this is already a Err, do nothing
|
|
|
|
if e, ok := err.(Err); ok {
|
2018-05-08 22:04:36 -04:00
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show a generic message for known golang errors
|
2019-09-11 13:21:43 -04:00
|
|
|
if errors.Is(err, syscall.EADDRINUSE) {
|
2019-10-04 13:35:33 -04:00
|
|
|
return ErrPortAlreadyInUse(err).Msg("Specified port is already in use")
|
2020-01-03 10:45:26 -05:00
|
|
|
} else if errors.Is(err, syscall.EACCES) || errors.Is(err, syscall.EPERM) {
|
|
|
|
switch err.(type) {
|
|
|
|
case *net.OpError:
|
|
|
|
return ErrPortAccess(err).Msg("Insufficient permissions to use specified port")
|
|
|
|
}
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
2020-10-01 16:23:31 -04:00
|
|
|
|
|
|
|
// Failed to identify what type of error this, return a simple UI error
|
|
|
|
return Err{msg: err.Error()}
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
|
|
|
|
2019-10-04 13:35:33 -04:00
|
|
|
// FmtError converts a fatal error message to a more clear error
|
2018-05-08 22:04:36 -04:00
|
|
|
// using some colors
|
2019-10-04 13:35:33 -04:00
|
|
|
func FmtError(introMsg string, err error, jsonFlag bool) string {
|
2020-10-01 16:23:31 -04:00
|
|
|
|
2018-05-08 22:04:36 -04:00
|
|
|
renderedTxt := ""
|
2019-10-04 13:35:33 -04:00
|
|
|
uiErr := ErrorToErr(err)
|
2018-05-08 22:04:36 -04:00
|
|
|
// JSON print
|
|
|
|
if jsonFlag {
|
|
|
|
// Message text in json should be simple
|
|
|
|
if uiErr.detail != "" {
|
|
|
|
return uiErr.msg + ": " + uiErr.detail
|
|
|
|
}
|
|
|
|
return uiErr.msg
|
|
|
|
}
|
|
|
|
// Pretty print error message
|
|
|
|
introMsg += ": "
|
|
|
|
if uiErr.msg != "" {
|
2019-10-04 13:35:33 -04:00
|
|
|
introMsg += color.Bold(uiErr.msg)
|
2018-05-08 22:04:36 -04:00
|
|
|
} else {
|
2019-10-04 13:35:33 -04:00
|
|
|
introMsg += color.Bold(err.Error())
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
2019-10-04 13:35:33 -04:00
|
|
|
renderedTxt += color.Red(introMsg) + "\n"
|
2018-05-08 22:04:36 -04:00
|
|
|
// Add action message
|
|
|
|
if uiErr.action != "" {
|
2019-10-04 13:35:33 -04:00
|
|
|
renderedTxt += "> " + color.BgYellow(color.Black(uiErr.action)) + "\n"
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
2019-08-13 00:25:34 -04:00
|
|
|
// Add hint
|
|
|
|
if uiErr.hint != "" {
|
2019-10-04 13:35:33 -04:00
|
|
|
renderedTxt += color.Bold("HINT:") + "\n"
|
2019-08-13 00:25:34 -04:00
|
|
|
renderedTxt += " " + uiErr.hint
|
2018-05-08 22:04:36 -04:00
|
|
|
}
|
|
|
|
return renderedTxt
|
|
|
|
}
|