discord-net / Discord.Net

An unofficial .Net wrapper for the Discord API (https://discord.com/)
https://discordnet.dev
MIT License
3.28k stars 743 forks source link

Requiring cultures does not seem necessary #2704

Open LucHeart opened 1 year ago

LucHeart commented 1 year ago

Discord.NET version

3.10.0

.NET version

7

Docker base image

mcr.microsoft.com/dotnet/runtime:7.0-alpine

Dockerfile to rep

FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine AS build

WORKDIR /src
COPY . .
WORKDIR "/src/DiscordBot"

RUN dotnet publish "DiscordBot.csproj" -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/runtime:7.0-alpine
WORKDIR /app
COPY --from=build /app/publish .

ENTRYPOINT ["dotnet", "DiscordBot.dll"]

csproj to rep

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <AssemblyVersion>1.0.0.0</AssemblyVersion>
        <FileVersion>1.0.0.0</FileVersion>
        <AssemblyName>DiscordBot</AssemblyName>
        <RootNamespace>DiscordBot</RootNamespace>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Discord.Addons.Hosting" Version="5.2.0" />
      <PackageReference Include="Discord.Net" Version="3.10.0" />
    </ItemGroup>

</Project>

Background information

We were trying to just run a empty bot on a alpine dotnet7 runtime base image in docker. However we were immediately greeted with the error:

18:55:47 Gateway     Connected
18:55:47 Gateway     Error handling Dispatch (GUILD_AVAILABLE):

System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')

en-US is an invalid culture identifier.

   at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride)

   at Discord.WebSocket.SocketGuild.Update(ClientState state, Guild model)

   at Discord.WebSocket.SocketGuild.Update(ClientState state, ExtendedGuild model)

   at Discord.WebSocket.DiscordSocketClient.ProcessMessageAsync(GatewayOpCode opCode, Nullable`1 seq, String type, Object payload)

We then figured out that Discord.NET requires en-US as a culture. So the fix was simple: Add <InvariantGlobalization>false</InvariantGlobalization> to your csproj and add RUN apk add --no-cache icu-libs to your dockerfile. That then fixed the issue we had so far, however I was questioning why it would require cultures. I think it should support running with invariant culture aswell.

So after talking to someone on the discord server about it they said it has the following reason and told us to open a github issue about it.

eggsbox on Discord.NET's discord server:

It's for registerring the PreferredCulture for a guild based on the Locale
so with it running in InvariantMode; and alpine having no cultures, it couldn't load it and dnet isn't safely catching it
I'd suggest raising it as an issue on the github with your stack trace.

Feel free to request any more information / reach out.

WardenDrew commented 8 months ago

Ran into the same issue. I had found the csproj flag but was missing the dockerfile change so that was helpful to find @LucHeart

Pretty much the same exception stack here:

fail: WardenBot.Discord.BackgroundServices.DiscordBackgroundService[0]
      [Gateway] Error handling Dispatch (GUILD_AVAILABLE)
      System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
      en-US is an invalid culture identifier.
         at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride)
         at Discord.WebSocket.SocketGuild.Update(ClientState state, Guild model)
         at Discord.WebSocket.SocketGuild.Update(ClientState state, ExtendedGuild model)
         at Discord.WebSocket.DiscordSocketClient.ProcessMessageAsync(GatewayOpCode opCode, Nullable`1 seq, String type, Object payload)
delasource commented 5 months ago

+1 here

if you have an application with <InvariantGlobalization>true</InvariantGlobalization> you can not use this library. Should be fixed asap, since some of the "dotnet new" templates come with this mode enabled by default!

rpendleton commented 3 months ago

Another way to reproduce issues related to this is to use dotnet's official chiseled Docker images. Similar to Alpine docker images, these chiseled images also exclude ICU data.

When I tried using Discord.NET with mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled, I ran into stack traces that match #2795. Switching to mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled-extra fixed those exceptions.