-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
persistence ok and zod on db entity #9
base: main
Are you sure you want to change the base?
Conversation
(aggiunte API) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Qualche commento sparso. Non so bene come volevate portare avanti il training o se volevate chiuderlo ora, quindi non è detto che abbia senso applicarli tutti, un paio sono più che altro commenti su come facciamo di solito queste cose.
@tpetrucciani Ho fatto delle modifiche seguendo le tue osservazioni. Se ti sembra tutto ok confermami, così inizio anche a scrivere la pagina Notion del training :) |
service/game.ts
Outdated
userMove: Move, | ||
computerMove: Move | ||
): Promise<string> { | ||
const outcome: string[] = match([userMove, computerMove]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggerirei di fare destructuring tipo
const outcome: string[] = match([userMove, computerMove]) | |
const [result, resultMessage] = match([userMove, computerMove]) |
per evitare di usare outcome[0]
e outcome[1]
nel seguito, che mi sembrano meno leggibili
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Che gioia, non avevo proprio considerato che si potesse usare destructuring in TS
service/game.ts
Outdated
@@ -50,11 +49,11 @@ export async function welcome(): Promise<string[]> { | |||
} | |||
} | |||
|
|||
export async function allGamesParsed(): Promise<Result[]> { | |||
export async function allGamesParsed(): Promise<Error | ResultArray> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tendenzialmente in TS è più idiomatico fare throw
nel caso di errori, generando quindi una Promise
fallita: perciò il tipo qui può restare solo Promise<ResultArray>
e poi fai un try
/catch
dove fai await
di questa promise
nulla vieta di restituire invece un'unione, e noi in progetti passati usavamo per esempio fp-ts con TaskEither
per usare un Either
nel risultato, ma ora di solito facciamo throw
in casi del genere (non rende esplicito l'errore nel tipo, naturalmente, quindi aumenta il rischio di scordarsi di gestirlo, ma in pratica gli errori da gestire esplicitametne sono pochi nelle nostre applicazioni tipiche)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ho scelto di restituire Promise<Error | ResultArray>
perchè in questo modo mi viene più semplice estrarre il messaggio di errore dal chiamante. Ho provato anche a lavorare sulla Promise
fallita, ma il messaggio di errore che mi arriva è quello di zod e non quello a monte. Questo probably è assimilabile all'uso di un Either
senza importare fp-ts
, immagino. Mi potresti mostrare uno snippet di come lo scriveresti pls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tendenzialmente farei così:
- qui userei
.parse
invece di.safeParse
e quindi cambierei il tipo di ritorno inPromise<ResultArray>
- dove lo usi farei
try { const allResults = await allGamesParsed(); return res .status(200) .json({ game_history: allResults, }) .end(); } catch (error) { ... }
Il problema è che error
avrà tipo unknown
e non Error
, perché in JS si può fare throw anche di cose che non sono Error
. Quindi poi per accedere al campo .message
devi fare un instanceof
.
In pratica però l'errore sarà lo stesso che hai nel campo .error
del risultato di safeParse
, perché parse
si limita a usare safeParse
e poi throw
. Quindi non dovrebbe essere un messaggio diverso, ma non so se ho capito "il messaggio di errore che mi arriva è quello di zod e non quello a monte".
(In generale mi torna che sia meglio usare safeParse
per assicurarsi di gestire l'errore, ma in caso come questo, in cui l'errore avviene solo in caso lo schema del DB è disallineato rispetto al codice, quindi in caso di bug, ci sta fare un parse
diretto per semplicità.)
Note: error mapping is still wip as well as testing