Skip to content

Instantly share code, notes, and snippets.

@mmyoji
Last active April 21, 2023 03:48
Show Gist options
  • Save mmyoji/5d02a25c167778f09f6891e223c64b4c to your computer and use it in GitHub Desktop.
Save mmyoji/5d02a25c167778f09f6891e223c64b4c to your computer and use it in GitHub Desktop.
Avoid throw function
// Suppose we have following code:
class APIError extends Error {}
function throwAPIError(message: string) {
// complicated logic...
throw new APIError(message);
}
export async function handleLogin(body: { username: string; encryptedPassword }): Promise<User> {
const result = validate(body);
if (!result.success) {
// This sucks
throwAPIError("invalid data");
}
return fetchUser(result.data.username);
}
// When we saw the `handleLogin`, we can't know the code stops in `throwAPIError`
// without looking at the function's implementation detail.
//
// Thus I prefer like this.
export async function handleLogin(body: { username: string; encryptedPassword }): Promise<User> {
const result = validate(body);
if (!result.success) {
return throwAPIError("invalid data");
}
return fetchUser(result.data.username);
}
// But the above code is still insufficient for me.
// We can improve it like this:
function buildAPIError(message: string): APIError {
// complicated logic...
return new APIError(message);
}
export async function handleLogin(body: { username: string; encryptedPassword }): Promise<User> {
const result = validate(body);
if (!result.success) {
throw buildAPIError("invalid data");
}
return fetchUser(result.data.username);
}
// I believe the last code is much more understandable though this may be a personal preference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment