Closed StanczakDominik closed 3 months ago
Sure you can assign to me.
EDIT: I can reproduce in dev environment.
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?
It looks like that screen has some "theoretical balance" screens. Have added fix in PR.
@jauggy, do you think I could ask you to adjust the
admin/matches/:match_id
page just like you did forbattle/:match_id
? I'm guessingadmin/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:
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: