package error import ( "fmt" ) const ( ErrDummy int = -1 ErrStorageFailure int = 1000 ErrGameStateInvalid int = 2000 ErrDeleteShipTypeExistingGroup = 5000 ErrDeleteShipTypePlanetProduction = 5001 ErrDeleteSciencePlanetProduction = 5002 ) const ( ErrInputUnknownHostRace int = 3000 + iota ErrInputUnknownOpponentRace ErrInputEntityTypeNameInvalid ErrInputEntityTypeNameDuplicate ErrInputEntityNotExists ErrInputEntityNotOwned ErrInputPlanetNumber ErrInputDriveValue ErrInputWeaponsValue ErrInputShieldsValue ErrInputCargoValue ErrInputShipTypeArmamentValue ErrInputShipTypeWeaponsAndArmamentValue ErrInputShipTypeZeroValues ErrInputScienceSumValues ErrInputProductionInvalid ) 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 ErrInputEntityTypeNameDuplicate: return "Name already exists" case ErrInputEntityNotExists: return "Entity does not exists" case ErrInputEntityNotOwned: return "Entity is not owned" case ErrInputPlanetNumber: return "Invalid Planet number" case ErrInputDriveValue: return "Invalid Drive value" case ErrInputWeaponsValue: return "Invalid Weapons value" case ErrInputShieldsValue: return "Invalid Shields value" case ErrInputCargoValue: 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" case ErrDeleteShipTypeExistingGroup: return "Ship type exists in a Group" case ErrDeleteShipTypePlanetProduction: return "Ship type in production on the Planet" case ErrDeleteSciencePlanetProduction: return "Science in production on the Planet" case ErrInputScienceSumValues: return "Science proportions sum should be equal 1" case ErrInputProductionInvalid: return "Invalid Production type" 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) } }