package error import ( "fmt" ) const ( ErrDummy int = -1 ErrStorageFailure int = 1000 ErrGameStateInvalid int = 2000 ErrDeleteShipTypeExistingGroup = 5000 ErrDeleteShipTypePlanetProduction = 5001 ErrDeleteSciencePlanetProduction = 5002 ErrMergeShipTypeNotEqual = 5003 ErrJoinFleetGroupNumberNotEnough = 5004 ErrBeakGroupNumberNotEnough = 5005 ErrEntityInUse = 5006 ErrShipsBusy = 5007 ErrShipsNotOnSamePlanet = 5008 ErrGiveawayGroupShipsTypeNotEqual = 5009 ) const ( ErrInputUnknownRace int = 3000 + iota ErrInputSameRace ErrInputEntityTypeNameInvalid ErrInputEntityTypeNameDuplicate ErrInputEntityTypeNameEquality ErrInputEntityNotExists ErrInputEntityNotOwned ErrInputPlanetNumber ErrInputDriveValue ErrInputWeaponsValue ErrInputShieldsValue ErrInputCargoValue ErrInputShipTypeArmamentValue ErrInputShipTypeWeaponsAndArmamentValue ErrInputShipTypeZeroValues ErrInputScienceSumValues ErrInputProductionInvalid ErrInputCargoTypeInvalid ErrInputCargoLoadNotEnough ErrInputCargoLoadNotEqual ErrInputCargoLoadNoCargoBay ErrInputCargoLoadNoSpaceLeft ) func GenericErrorText(code int) string { switch code { case ErrDummy: return "Dummy" case ErrStorageFailure: return "Storage failure" case ErrGameStateInvalid: return "Invalid game state" case ErrInputUnknownRace: return "Race name is unknown to this game" case ErrInputSameRace: return "Race name must be different from your own" case ErrInputEntityTypeNameInvalid: return "Name has invalid length or symbols" case ErrInputEntityTypeNameDuplicate: return "Name already exists" case ErrInputEntityTypeNameEquality: return "Names should differ" case ErrInputEntityNotExists: return "Entity does not exists" case ErrInputEntityNotOwned: return "Entity is not owned" case ErrEntityInUse: return "Entity currently in use" 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" case ErrInputCargoTypeInvalid: return "Invalid cargo type" case ErrInputCargoLoadNotEnough: return "Not enough cargo to load" case ErrInputCargoLoadNotEqual: return "Ship(s) already loaded with another cargo" case ErrInputCargoLoadNoCargoBay: return "Ship type is not designed to carry cargo" case ErrInputCargoLoadNoSpaceLeft: return "No space left on the ships to load cargo" case ErrMergeShipTypeNotEqual: return "Source and target ship types are not the same" case ErrJoinFleetGroupNumberNotEnough: return "Not enough ships in the group to join a fleet" case ErrBeakGroupNumberNotEnough: return "Not enough ships in the group to make a separate group" case ErrShipsBusy: return "Ships currently not in orbit or free to use" case ErrShipsNotOnSamePlanet: return "Ships not on the same planet" case ErrGiveawayGroupShipsTypeNotEqual: return "Ship type already defined with different specifications" 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) } }