package error import ( "fmt" ) const ( ErrDummy int = -1 ErrStorageFailure int = 1000 ErrGameStateInvalid int = 2000 ) const ( ErrInputUnknownHostRace int = 3000 + iota ErrInputUnknownOpponentRace ErrInputEntityTypeNameInvalid ErrInputEntityTypeNameExists ErrInputShipTypeDriveValue ErrInputShipTypeWeaponsValue ErrInputShipTypeShieldsValue ErrInputShipTypeCargoValue ErrInputShipTypeArmamentValue ErrInputShipTypeWeaponsAndArmamentValue ErrInputShipTypeZeroValues ) func GenericErrorText(code int) string { switch code { case ErrDummy: return "Dummy" case ErrStorageFailure: return "Storage failure" case ErrGameStateInvalid: return "Invalid game state" case ErrInputUnknownHostRace: return "Host race name is unknown to this game" case ErrInputUnknownOpponentRace: return "Opponent race name is unknown to this game" case ErrInputEntityTypeNameInvalid: return "Name has invalid length or symbols" case ErrInputEntityTypeNameExists: return "Name already exists" case ErrInputShipTypeDriveValue: return "Invalid Drive value" case ErrInputShipTypeWeaponsValue: return "Invalid Weapons value" case ErrInputShipTypeShieldsValue: return "Invalid Shields value" case ErrInputShipTypeCargoValue: return "Invalid Cargo value" case ErrInputShipTypeArmamentValue: return "Invalid Armament value" case ErrInputShipTypeWeaponsAndArmamentValue: return "Invalid Armament or Weapons value" case ErrInputShipTypeZeroValues: return "Ship type values cannot be all zeros" default: return fmt.Sprintf("Undescribed error with code %d", code) } } type GenericError struct { code int subject string err error } func (ge GenericError) Error() string { msg := GenericErrorText(ge.code) if ge.subject != "" { msg += ": " + ge.subject } if ge.err != nil { msg = fmt.Errorf("%s: %w", msg, ge.err).Error() } return msg } func newGenericError(code int, arg ...any) error { e := &GenericError{code: code} if len(arg) > 0 { i := 0 switch arg[i].(type) { case error: e.err = arg[i].(error) i += 1 } if len(arg) == i+2 { e.subject = fmt.Sprintf(asString(arg[i]), arg[i+1:]...) } else if len(arg) == i+1 { e.subject = asString(arg[i]) } } return *e } func asString(v any) string { switch s := v.(type) { case string: return s default: return fmt.Sprint(v) } }