Handle game not found errors in landing page

landing-page-layout
MiguelMLorente 2025-02-09 22:52:15 +01:00
parent 1d777f74ff
commit e7ea4269d7
7 changed files with 51 additions and 11 deletions

View File

@ -17,6 +17,7 @@ import {
} from 'interface';
import { createWsExceptionFilter } from './websocket-exception-filter';
import {
GameNotFoundException,
InvalidPlayerNameException,
MissingPlayerNameException,
PlayerNotFoundException,
@ -62,6 +63,7 @@ export class AppService implements OnGatewayConnection {
PlayerNotFoundException,
MissingPlayerNameException,
InvalidPlayerNameException,
GameNotFoundException,
]),
)
@SubscribeMessage(ClientEvent.JOIN_LOBBY)

View File

@ -2,6 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { Game } from './game';
import { v4 as uuidv4 } from 'uuid';
import { Player } from 'src/players/player';
import { GameNotFoundException } from 'src/exceptions';
@Injectable()
export class GameService {
@ -19,7 +20,7 @@ export class GameService {
joinGame(player: Player, gameCode: string): Game {
const game = this.games.get(gameCode);
if (game === undefined) {
throw Error('No se ha encontrado el Lobby');
throw new GameNotFoundException(gameCode);
}
game.players.push(player);
return game;

View File

@ -11,7 +11,7 @@ import { Socket } from 'socket.io/dist/socket';
export class PlayerService {
private readonly logger = new Logger(PlayerService.name);
private readonly players: Map<string, Player> = new Map();
private readonly userNameValidator: RegExp = /(^[a-zA-Z]){1,20}$/;
private readonly userNameValidator: RegExp = /^[a-zA-Z\s]{1,20}$/;
createPlayer(socket: Socket) {
const player: Player = new Player(socket);

View File

@ -3,7 +3,7 @@ import { BaseWsExceptionFilter } from '@nestjs/websockets';
import { WebSocketException } from './exceptions';
import { Socket } from 'socket.io';
import { ClientEvent } from 'interface';
import { emitCreateLobbyError } from 'interface';
import { emitCreateLobbyError, emitJoinLobbyError } from 'interface';
export const createWsExceptionFilter: (
exceptionList: (typeof WebSocketException)[],
@ -27,6 +27,8 @@ export const createWsExceptionFilter: (
case ClientEvent.CREATE_LOBBY:
emitCreateLobbyError(socket, { error: exception.errorCode });
break;
case ClientEvent.JOIN_LOBBY:
emitJoinLobbyError(socket, { error: exception.errorCode });
}
}
}

View File

@ -5,6 +5,7 @@ export * from "./constants/InternalNodeType";
export * from "./constants/Pieces";
export * from "./constants/TrackType";
export * from "./server-events/CreateLobbyError";
export * from "./server-events/JoinLobbyError";
export * from "./server-events/ServerError";
export * from "./server-events/ServerEvent";
export * from "./server-events/StartRoundEvent";

View File

@ -0,0 +1,22 @@
import { Socket as ServerSocket } from "socket.io";
import { Socket as ClientSocket } from "socket.io-client";
import { ErrorCode, ServerError } from "./ServerError";
export type JoinLobbyError = {
error: ErrorCode;
};
export const emitJoinLobbyError = (
socket: ServerSocket,
payload: JoinLobbyError,
) => {
socket.emit(ServerError.JOIN_LOBBY_ERROR, payload);
};
export const attachHandlerToJoinLobbyError = (
socket: ClientSocket,
handler: (payload: JoinLobbyError) => void,
): (() => void) => {
socket.on(ServerError.JOIN_LOBBY_ERROR, handler);
return () => socket.off(ServerError.JOIN_LOBBY_ERROR);
};

View File

@ -1,12 +1,13 @@
import {
attachHandlerToCreateLobbyError,
attachHandlerToJoinLobbyError,
CreateLobbyEvent,
ErrorCode,
handleCreateLobby,
handleJoinLobby,
JoinLobbyEvent,
} from "interface";
import React, { ChangeEvent, useState } from "react";
import { ChangeEvent, useState } from "react";
import { Socket } from "socket.io-client";
import "./LandingPage.scss";
@ -17,14 +18,14 @@ export interface LandingPageProps {
const LandingPage = (props: LandingPageProps) => {
const { socket } = props;
const createLobbyPayload: CreateLobbyEvent = { userName: "" };
const joinLobbyPayload: JoinLobbyEvent = { userName: "", lobbyId: "" };
const registerUsername = (event: ChangeEvent<HTMLInputElement>) => {
createLobbyPayload.userName = event.target.value;
joinLobbyPayload.userName = event.target.value;
};
const [userName, setUsername] = useState("");
const [lobbyId, setLobbyId] = useState("");
const createLobbyPayload: CreateLobbyEvent = { userName };
const joinLobbyPayload: JoinLobbyEvent = { userName, lobbyId };
const registerUsername = (event: ChangeEvent<HTMLInputElement>) =>
setUsername(event.target.value);
const registerLobbyId = (event: ChangeEvent<HTMLInputElement>) =>
(joinLobbyPayload.lobbyId = event.target.value);
setLobbyId(event.target.value);
const [receivedError, setReceivedError] = useState("" as ErrorCode);
const userNameErrorCodesToMessageMap = new Map([
@ -36,10 +37,18 @@ const LandingPage = (props: LandingPageProps) => {
]);
const userNameErrorMessage =
userNameErrorCodesToMessageMap.get(receivedError);
const gameCodeErrorCodesToMessageMap = new Map([
[ErrorCode.GAME_NOT_FOUND, "No game found with such lobby ID"],
]);
const gameCodeErrorMessage =
gameCodeErrorCodesToMessageMap.get(receivedError);
attachHandlerToCreateLobbyError(socket, (event) =>
setReceivedError(event.error),
);
attachHandlerToJoinLobbyError(socket, (event) =>
setReceivedError(event.error),
);
return (
<div className="landing-page">
@ -66,6 +75,9 @@ const LandingPage = (props: LandingPageProps) => {
onChange={registerLobbyId}
maxLength={5}
></input>
{gameCodeErrorMessage && (
<small id="error-message">{gameCodeErrorMessage}</small>
)}
<button
className="secondary"
onClick={() => handleJoinLobby(socket, joinLobbyPayload)}