Skip to content

Commit

Permalink
エラーを返すときの形式をGoと同じJSON形式にする
Browse files Browse the repository at this point in the history
  • Loading branch information
pastak committed Dec 2, 2024
1 parent f7dc40f commit 46ea04b
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 56 deletions.
90 changes: 60 additions & 30 deletions webapp/nodejs/src/app_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
FARE_PER_DISTANCE,
getLatestRideStatus,
INITIAL_FARE,
responseError,
} from "./common.js";
import type { CountResult } from "./types/util.js";
import { requestPaymentGatewayPostPayment } from "./payment_gateway.js";
Expand All @@ -47,8 +48,11 @@ export const appPostUsers = async (ctx: Context<Environment>) => {
reqJson.lastname === "" ||
reqJson.date_of_birth === ""
) {
return ctx.text(
"required fields(username, firstname, lastname, date_of_birth) are empty",
return responseError(
ctx,
new Error(
"required fields(username, firstname, lastname, date_of_birth) are empty",
),
400,
);
}
Expand Down Expand Up @@ -86,7 +90,11 @@ export const appPostUsers = async (ctx: Context<Environment>) => {
`INV_${reqJson.invitation_code}`,
);
if (coupons.length >= 3) {
return ctx.text("この招待コードは使用できません。", 400);
return responseError(
ctx,
new Error("この招待コードは使用できません。"),
400,
);
}

// ユーザーチェック
Expand All @@ -95,7 +103,11 @@ export const appPostUsers = async (ctx: Context<Environment>) => {
[reqJson.invitation_code],
);
if (inviter.length === 0) {
return ctx.text("この招待コードは使用できません。", 400);
return responseError(
ctx,
new Error("この招待コードは使用できません。"),
400,
);
}

// 招待クーポン付与
Expand Down Expand Up @@ -124,14 +136,18 @@ export const appPostUsers = async (ctx: Context<Environment>) => {
);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

export const appPostPaymentMethods = async (ctx: Context<Environment>) => {
const reqJson = await ctx.req.json<{ token: string }>();
if (reqJson.token === "") {
return ctx.text("token is required but was empty", 400);
return responseError(
ctx,
new Error("token is required but was empty"),
400,
);
}
const user = ctx.var.user;
await ctx.var.dbConn.query(
Expand Down Expand Up @@ -220,7 +236,7 @@ export const appGetRides = async (ctx: Context<Environment>) => {
);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

Expand All @@ -230,8 +246,11 @@ export const appPostRides = async (ctx: Context<Environment>) => {
destination_coordinate: Coordinate;
}>();
if (!reqJson.pickup_coordinate || !reqJson.destination_coordinate) {
return ctx.text(
"required fields(pickup_coordinate, destination_coordinate) are empty",
return responseError(
ctx,
new Error(
"required fields(pickup_coordinate, destination_coordinate) are empty",
),
400,
);
}
Expand All @@ -251,7 +270,7 @@ export const appPostRides = async (ctx: Context<Environment>) => {
}
}
if (continuingRideCount > 0) {
return ctx.text("ride already exists", 409);
return responseError(ctx, new Error("ride already exists"), 409);
}
await ctx.var.dbConn.query(
"INSERT INTO rides (id, user_id, pickup_latitude, pickup_longitude, destination_latitude, destination_longitude) VALUES (?, ?, ?, ?, ?, ?)",
Expand Down Expand Up @@ -336,7 +355,7 @@ export const appPostRides = async (ctx: Context<Environment>) => {
);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

Expand All @@ -346,8 +365,11 @@ export const appPostRidesEstimatedFare = async (ctx: Context<Environment>) => {
destination_coordinate: Coordinate;
}>();
if (!reqJson.pickup_coordinate || !reqJson.destination_coordinate) {
return ctx.text(
"required fields(pickup_coordinate, destination_coordinate) are empty",
return responseError(
ctx,
new Error(
"required fields(pickup_coordinate, destination_coordinate) are empty",
),
400,
);
}
Expand Down Expand Up @@ -379,15 +401,19 @@ export const appPostRidesEstimatedFare = async (ctx: Context<Environment>) => {
);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

export const appPostRideEvaluatation = async (ctx: Context<Environment>) => {
const rideId = ctx.req.param("ride_id");
const reqJson = await ctx.req.json<{ evaluation: number }>();
if (reqJson.evaluation < 1 || reqJson.evaluation > 5) {
return ctx.text("evaluation must be between 1 and 5", 400);
return responseError(
ctx,
new Error("evaluation must be between 1 and 5"),
400,
);
}
await ctx.var.dbConn.beginTransaction();
try {
Expand All @@ -396,19 +422,19 @@ export const appPostRideEvaluatation = async (ctx: Context<Environment>) => {
rideId,
);
if (!ride) {
return ctx.text("ride not found", 404);
return responseError(ctx, new Error("ride not found"), 404);
}
const status = await getLatestRideStatus(ctx.var.dbConn, ride.id);
if (status !== "ARRIVED") {
return ctx.text("not arrived yet", 400);
return responseError(ctx, new Error("ride not arrived yet"), 400);
}

const [result] = await ctx.var.dbConn.query<ResultSetHeader>(
"UPDATE rides SET evaluation = ? WHERE id = ?",
[reqJson.evaluation, rideId],
);
if (result.affectedRows === 0) {
return ctx.text("ride not found", 404);
return responseError(ctx, new Error("ride not found"), 404);
}

await ctx.var.dbConn.query(
Expand All @@ -421,14 +447,14 @@ export const appPostRideEvaluatation = async (ctx: Context<Environment>) => {
rideId,
);
if (!ride) {
return ctx.text("ride not found", 404);
return responseError(ctx, new Error("ride not found"), 404);
}

const [[paymentToken]] = await ctx.var.dbConn.query<
Array<PaymentToken & RowDataPacket>
>("SELECT * FROM payment_tokens WHERE user_id = ?", [ride.user_id]);
if (!paymentToken) {
return ctx.text("payment token not registered", 400);
return responseError(ctx, new Error("payment token not registered"), 400);
}
const fare = await calculateDiscountedFare(
ctx.var.dbConn,
Expand Down Expand Up @@ -457,7 +483,7 @@ export const appPostRideEvaluatation = async (ctx: Context<Environment>) => {
},
);
if (err instanceof ErroredUpstream) {
return ctx.text(`${err}`, 502);
return responseError(ctx, err, 502);
}
await ctx.var.dbConn.commit();
return ctx.json(
Expand All @@ -466,9 +492,9 @@ export const appPostRideEvaluatation = async (ctx: Context<Environment>) => {
},
200,
);
} catch (err) {
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${err}`, 500);
return responseError(ctx, e, 500);
}
};

Expand Down Expand Up @@ -571,7 +597,7 @@ export const appGetNotification = async (ctx: Context<Environment>) => {
return ctx.json(response, 200);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

Expand Down Expand Up @@ -631,23 +657,27 @@ export const appGetNearbyChairs = async (ctx: Context<Environment>) => {
const lonStr = ctx.req.query("longitude");
const distanceStr = ctx.req.query("distance");
if (!latStr || !lonStr) {
return ctx.text("latitude and longitude is empty", 400);
return responseError(
ctx,
new Error("latitude and longitude is empty"),
400,
);
}

const lat = atoi(latStr);
if (lat === false) {
return ctx.text("latitude is invalid", 400);
return responseError(ctx, new Error("latitude is invalid"), 400);
}
const lon = atoi(lonStr);
if (lon === false) {
return ctx.text("longitude is invalid", 400);
return responseError(ctx, new Error("longitude is invalid"), 400);
}

let distance: number | false = 50;
if (distanceStr) {
distance = atoi(distanceStr);
if (distance === false) {
return ctx.text("distance is invalid", 400);
return responseError(ctx, new Error("distance is invalid"), 400);
}
}

Expand Down Expand Up @@ -722,9 +752,9 @@ export const appGetNearbyChairs = async (ctx: Context<Environment>) => {
},
200,
);
} catch (err) {
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${err}`, 500);
return responseError(ctx, e, 500);
}
};

Expand Down
31 changes: 19 additions & 12 deletions webapp/nodejs/src/chair_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Context } from "hono";
import { setCookie } from "hono/cookie";
import type { RowDataPacket } from "mysql2";
import { ulid } from "ulid";
import { getLatestRideStatus } from "./common.js";
import { getLatestRideStatus, responseError } from "./common.js";
import type { Environment } from "./types/hono.js";
import type {
ChairLocation,
Expand All @@ -22,8 +22,11 @@ export const chairPostChairs = async (ctx: Context<Environment>) => {
}>();
const { name, model, chair_register_token } = reqJson;
if (!name || !model || !chair_register_token) {
return ctx.text(
"some of required fields(name, model, chair_register_token) are empty",
return responseError(
ctx,
new Error(
"some of required fields(name, model, chair_register_token) are empty",
),
400,
);
}
Expand All @@ -32,7 +35,7 @@ export const chairPostChairs = async (ctx: Context<Environment>) => {
[chair_register_token],
);
if (!owner) {
return ctx.text("invalid chair_register_token", 401);
return responseError(ctx, new Error("invalid chair_register_token"), 401);
}
const chairID = ulid();
const accessToken = secureRandomStr(32);
Expand All @@ -55,7 +58,7 @@ export const chairPostActivity = async (ctx: Context<Environment>) => {
chair.id,
]);
} catch (e) {
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
return ctx.body(null, 204);
};
Expand Down Expand Up @@ -106,7 +109,7 @@ export const chairPostCoordinate = async (ctx: Context<Environment>) => {
return ctx.json({ recorded_at: location.created_at.getTime() }, 200);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

Expand Down Expand Up @@ -169,7 +172,7 @@ export const chairGetNotification = async (ctx: Context<Environment>) => {
);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};

Expand All @@ -184,10 +187,10 @@ export const chairPostRideStatus = async (ctx: Context<Environment>) => {
[rideID],
);
if (!ride) {
return ctx.text("ride not found", 404);
return responseError(ctx, new Error("ride not found"), 404);
}
if (ride.chair_id !== chair.id) {
return ctx.text("not assigned to this ride", 400);
return responseError(ctx, new Error("cnot assigned to this ride"), 400);
}
switch (reqJson.status) {
// Acknowledge the ride
Expand All @@ -201,7 +204,11 @@ export const chairPostRideStatus = async (ctx: Context<Environment>) => {
case "CARRYING": {
const status = await getLatestRideStatus(ctx.var.dbConn, ride.id);
if (status !== "PICKUP") {
return ctx.text("chair has not arrived yet", 400);
return responseError(
ctx,
new Error("chair has not arrived yet"),
400,
);
}
await ctx.var.dbConn.query(
"INSERT INTO ride_statuses (id, ride_id, status) VALUES (?, ?, ?)",
Expand All @@ -210,12 +217,12 @@ export const chairPostRideStatus = async (ctx: Context<Environment>) => {
break;
}
default:
return ctx.text("invalid status", 400);
return responseError(ctx, new Error("invalid status"), 400);
}
await ctx.var.dbConn.commit();
return ctx.body(null, 204);
} catch (e) {
await ctx.var.dbConn.rollback();
return ctx.text(`${e}`, 500);
return responseError(ctx, e, 500);
}
};
13 changes: 13 additions & 0 deletions webapp/nodejs/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Connection, RowDataPacket } from "mysql2/promise";
import type { Ride, RideStatus } from "./types/models.js";
import type { Context } from "hono";
import type { StatusCode } from "hono/utils/http-status";

export const INITIAL_FARE = 500;
export const FARE_PER_DISTANCE = 100;
Expand Down Expand Up @@ -59,3 +61,14 @@ export class ErroredUpstream extends Error {
this.name = "ErroredUpstream";
}
}

export const responseError = (
ctx: Context,
error: unknown,
statusCode: StatusCode,
) => {
if (error instanceof Error) {
return ctx.json({ message: error.message }, statusCode);
}
throw new Error("error is not an instance of Error");
};
Loading

0 comments on commit 46ea04b

Please sign in to comment.