beyond-all-reason / teiserver

Middleware server for online gaming
https://www.beyondallreason.info/
MIT License
55 stars 53 forks source link

`/teiserver/admin/matches/:match_id` fails, while `/battle/:match_id/ratings` works, after #235 #314

Closed StanczakDominik closed 3 months ago

StanczakDominik commented 3 months ago

@jauggy, do you think I could ask you to adjust the admin/matches/:match_id page just like you did for battle/:match_id? I'm guessing admin/match_controller.ex needs to get updated arguments but I'm out of mana to fix it at the moment :(

Here's an example of a match it fails on:

image

Phoenix logs, these should be enough # KeyError at GET /teiserver/admin/matches/2783079 Exception: ** (KeyError) key :rating not found in: 31.785895067571246. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map (teiserver 0.1.0) lib/teiserver/battle/libs/balance_lib.ex:109: anonymous fn/1 in Teiserver.Battle.BalanceLib.create_balance/3 (elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2 (teiserver 0.1.0) lib/teiserver/battle/libs/balance_lib.ex:109: anonymous fn/1 in Teiserver.Battle.BalanceLib.create_balance/3 (elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2 (teiserver 0.1.0) lib/teiserver/battle/libs/balance_lib.ex:107: Teiserver.Battle.BalanceLib.create_balance/3 (teiserver 0.1.0) lib/teiserver_web/controllers/admin/match_controller.ex:134: TeiserverWeb.Admin.MatchController.show/2 (teiserver 0.1.0) lib/teiserver_web/controllers/admin/match_controller.ex:1: TeiserverWeb.Admin.MatchController.action/2 (teiserver 0.1.0) lib/teiserver_web/controllers/admin/match_controller.ex:1: TeiserverWeb.Admin.MatchController.phoenix_controller_pipeline/2 (phoenix 1.7.6) lib/phoenix/router.ex:430: Phoenix.Router.__call__/5 (teiserver 0.1.0) lib/teiserver_web/endpoint.ex:1: TeiserverWeb.Endpoint.plug_builder_call/2 (teiserver 0.1.0) lib/plug/debugger.ex:136: TeiserverWeb.Endpoint."call (overridable 3)"/2 (teiserver 0.1.0) lib/teiserver_web/endpoint.ex:1: TeiserverWeb.Endpoint.call/2 (phoenix 1.7.6) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4 (plug_cowboy 2.6.1) lib/plug/cowboy/handler.ex:11: Plug.Cowboy.Handler.init/2 (cowboy 2.10.0) deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2 (cowboy 2.10.0) deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3 (cowboy 2.10.0) deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3 (stdlib 5.2.3) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 Code: `lib/teiserver/battle/libs/balance_lib.ex` 104 # an ID that's used purely for this run of balance 105 expanded_groups = 106 groups 107 |> Enum.map(fn members -> 108 userids = Map.keys(members) 109> ratings = Map.values(members) |> Enum.map(fn x -> x.rating end) 110 111 ranks = 112 Map.values(members) 113 |> Enum.map(fn x -> 114 cond do `lib/enum.ex` No code available. `lib/teiserver/battle/libs/balance_lib.ex` 104 # an ID that's used purely for this run of balance 105 expanded_groups = 106 groups 107 |> Enum.map(fn members -> 108 userids = Map.keys(members) 109> ratings = Map.values(members) |> Enum.map(fn x -> x.rating end) 110 111 ranks = 112 Map.values(members) 113 |> Enum.map(fn x -> 114 cond do `lib/enum.ex` No code available. `lib/teiserver/battle/libs/balance_lib.ex` 102 103 # We perform all our group calculations here and assign each group 104 # an ID that's used purely for this run of balance 105 expanded_groups = 106 groups 107> |> Enum.map(fn members -> 108 userids = Map.keys(members) 109 ratings = Map.values(members) |> Enum.map(fn x -> x.rating end) 110 111 ranks = 112 Map.values(members) `lib/teiserver_web/controllers/admin/match_controller.ex` 129 end) 130 end) 131 |> List.flatten() 132 133 past_balance = 134> BalanceLib.create_balance(groups, match.team_count, mode: :loser_picks) 135 |> Map.put(:balance_mode, :grouped) 136 137 # What about new balance? 138 new_balance = generate_new_balance_data(match) 139 `lib/teiserver_web/controllers/admin/match_controller.ex` 1> defmodule TeiserverWeb.Admin.MatchController do 2 use TeiserverWeb, :controller 3 4 alias Teiserver.{Battle, Game, Account, Telemetry} 5 alias Teiserver.Battle.{MatchLib, BalanceLib} 6 import Teiserver.Helper.StringHelper, only: [get_hash_id: 1] `lib/teiserver_web/controllers/admin/match_controller.ex` 1> defmodule TeiserverWeb.Admin.MatchController do 2 use TeiserverWeb, :controller 3 4 alias Teiserver.{Battle, Game, Account, Telemetry} 5 alias Teiserver.Battle.{MatchLib, BalanceLib} 6 import Teiserver.Helper.StringHelper, only: [get_hash_id: 1] `lib/phoenix/router.ex` 425 :telemetry.execute([:phoenix, :router_dispatch, :stop], measurements, metadata) 426 halted_conn 427 428 %Plug.Conn{} = piped_conn -> 429 try do 430> plug.call(piped_conn, plug.init(opts)) 431 else 432 conn -> 433 measurements = %{duration: System.monotonic_time() - start} 434 metadata = %{metadata | conn: conn} 435 :telemetry.execute([:phoenix, :router_dispatch, :stop], measurements, metadata) `lib/teiserver_web/endpoint.ex` 1> defmodule TeiserverWeb.Endpoint do 2 use Phoenix.Endpoint, otp_app: :teiserver 3 4 @session_options [ 5 store: :cookie, 6 key: "_teiserver_key", `lib/plug/debugger.ex` No code available. `lib/teiserver_web/endpoint.ex` 1> defmodule TeiserverWeb.Endpoint do 2 use Phoenix.Endpoint, otp_app: :teiserver 3 4 @session_options [ 5 store: :cookie, 6 key: "_teiserver_key", `lib/phoenix/endpoint/sync_code_reload_plug.ex` 17 18 def call(conn, {endpoint, opts}), do: do_call(conn, endpoint, opts, true) 19 20 defp do_call(conn, endpoint, opts, retry?) do 21 try do 22> endpoint.call(conn, opts) 23 rescue 24 exception in [UndefinedFunctionError] -> 25 case exception do 26 %UndefinedFunctionError{module: ^endpoint} when retry? -> 27 # Sync with the code reloader and retry once `lib/plug/cowboy/handler.ex` 6 def init(req, {plug, opts}) do 7 conn = @connection.conn(req) 8 9 try do 10 conn 11> |> plug.call(opts) 12 |> maybe_send(plug) 13 |> case do 14 %Plug.Conn{adapter: {@connection, %{upgrade: {:websocket, websocket_args}} = req}} = conn -> 15 {handler, state, cowboy_opts} = websocket_args 16 {__MODULE__, copy_resp_headers(conn, req), {handler, state}, cowboy_opts} `deps/cowboy/src/cowboy_handler.erl` 32 -optional_callbacks([terminate/3]). 33 34 -spec execute(Req, Env) -> {ok, Req, Env} 35 when Req::cowboy_req:req(), Env::cowboy_middleware:env(). 36 execute(Req, Env=#{handler := Handler, handler_opts := HandlerOpts}) -> 37> try Handler:init(Req, HandlerOpts) of 38 {ok, Req2, State} -> 39 Result = terminate(normal, Req2, State, Handler), 40 {ok, Req2, Env#{result => Result}}; 41 {Mod, Req2, State} -> 42 Mod:upgrade(Req2, Env, Handler, State); `deps/cowboy/src/cowboy_stream_h.erl` 301 end. 302 303 execute(_, _, []) -> 304 ok; 305 execute(Req, Env, [Middleware|Tail]) -> 306> case Middleware:execute(Req, Env) of 307 {ok, Req2, Env2} -> 308 execute(Req2, Env2, Tail); 309 {suspend, Module, Function, Args} -> 310 proc_lib:hibernate(?MODULE, resume, [Env, Tail, Module, Function, Args]); 311 {stop, _Req2} -> `deps/cowboy/src/cowboy_stream_h.erl` 290 %% to simplify the debugging of errors. The proc_lib library 291 %% already adds the stacktrace to other types of exceptions. 292 -spec request_process(cowboy_req:req(), cowboy_middleware:env(), [module()]) -> ok. 293 request_process(Req, Env, Middlewares) -> 294 try 295> execute(Req, Env, Middlewares) 296 catch 297 exit:Reason={shutdown, _}:Stacktrace -> 298 erlang:raise(exit, Reason, Stacktrace); 299 exit:Reason:Stacktrace when Reason =/= normal, Reason =/= shutdown -> 300 erlang:raise(exit, {Reason, Stacktrace}, Stacktrace) `proc_lib.erl` No code available. ## Connection details ### Params %{"id" => "2783079"} ### Request info * URI: .../teiserver/admin/matches/2783079 * Query string:
jauggy commented 3 months ago

Sure you can assign to me.

EDIT: I can reproduce in dev environment.

jauggy commented 3 months ago

I'm a little confused what the purpose of this page is. It seems to be creating balance on a past match? But if the match had auto balance off then it's just showing the wrong thing. Is this showing matches in progress or matches already completed?

jauggy commented 3 months ago

It looks like that screen has some "theoretical balance" screens. Have added fix in PR.