Skip to content

Commit

Permalink
perf: implement sentry
Browse files Browse the repository at this point in the history
  • Loading branch information
newarifrh committed Aug 25, 2024
1 parent 6c64e08 commit a03dc58
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 94 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:
run: |
docker build \
--build-arg BUILD_HASH=$SHORT_SHA \
--build-arg SENTRY_ORG=${{ secrets.SENTRY_ORG }} \
--build-arg SENTRY_PROJECT=${{ secrets.SENTRY_PROJECT }} \
--build-arg SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
-f Dockerfile.production \
-t ${{ secrets.DOCKER_REGISTRY_URL }}/${{ secrets.DOCKER_REGISTRY_USERNAME }}/serambi-kami:$VERSION \
-t ${{ secrets.DOCKER_REGISTRY_URL }}/${{ secrets.DOCKER_REGISTRY_USERNAME }}/serambi-kami:latest \
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:
run: |
docker build \
--build-arg BUILD_HASH=$SHORT_SHA \
--build-arg SENTRY_ORG=${{ secrets.SENTRY_ORG }} \
--build-arg SENTRY_PROJECT=${{ secrets.SENTRY_PROJECT }} \
--build-arg SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
-f Dockerfile.staging \
-t ${{ secrets.DOCKER_REGISTRY_URL }}/${{ secrets.DOCKER_REGISTRY_USERNAME }}/serambi-kami:latest \
.
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?

# Sentry Config File
.env.sentry-build-plugin
21 changes: 20 additions & 1 deletion Dockerfile.production
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
FROM oven/bun:1.1.25-alpine AS build-stage
# Build stage
FROM oven/bun:1.1.26-alpine AS build-stage

WORKDIR /app

COPY package.json bun.lockb ./

RUN bun install

COPY . .

ARG BUILD_HASH
ENV VITE_BUILD_HASH=${BUILD_HASH}

ARG SENTRY_ORG
ENV SENTRY_ORG=${SENTRY_ORG}

ARG SENTRY_PROJECT
ENV SENTRY_PROJECT=${SENTRY_PROJECT}

ARG SENTRY_AUTH_TOKEN
ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}

RUN bun run build-only --mode production

# Production stage
FROM nginx:stable-alpine-slim AS production-stage

RUN mkdir /app

COPY --from=build-stage /app/dist /app
COPY default.conf /etc/nginx/conf.d/default.conf
21 changes: 20 additions & 1 deletion Dockerfile.staging
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
FROM oven/bun:1.1.25-alpine AS build-stage
# Build stage
FROM oven/bun:1.1.26-alpine AS build-stage

WORKDIR /app

COPY package.json bun.lockb ./

RUN bun install

COPY . .

ARG BUILD_HASH
ENV VITE_BUILD_HASH=${BUILD_HASH}

ARG SENTRY_ORG
ENV SENTRY_ORG=${SENTRY_ORG}

ARG SENTRY_PROJECT
ENV SENTRY_PROJECT=${SENTRY_PROJECT}

ARG SENTRY_AUTH_TOKEN
ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}

RUN bun run build-only --mode staging

# Staging stage
FROM nginx:stable-alpine-slim AS staging-stage

RUN mkdir /app

COPY --from=build-stage /app/dist /app
COPY default.conf /etc/nginx/conf.d/default.conf
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
},
"dependencies": {
"@ant-design/icons": "^5.4.0",
"@sentry/react": "^8.26.0",
"antd": "^5.20.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.1"
},
"devDependencies": {
"@eslint/js": "^9.9.1",
"@sentry/vite-plugin": "^2.22.2",
"@types/bun": "^1.1.6",
"@types/node": "^22.5.0",
"@types/react": "^18.3.4",
Expand Down
9 changes: 2 additions & 7 deletions src/api/Auth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { API_BASE_URL } from "@/configs/Constant";
import { handleResponse } from "@/utils/Response";

export const login = async (email: string, password: string) => {
const response = await fetch(`${API_BASE_URL}/v1/auth/login`, {
Expand All @@ -11,11 +12,5 @@ export const login = async (email: string, password: string) => {
body: JSON.stringify({ email, password }),
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};
49 changes: 10 additions & 39 deletions src/api/Service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { API_BASE_URL } from "@/configs/Constant";
import { Service } from "@/types/Service";
import { handleResponse } from "@/utils/Response";

export const getServices = async (
keyword: string,
Expand All @@ -21,13 +22,10 @@ export const getServices = async (
}
);

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data as { services: Service[]; total: number };
return (await handleResponse(response)) as {
services: Service[];
total: number;
};
};

export const getServiceTags = async (type?: string) => {
Expand All @@ -43,27 +41,15 @@ export const getServiceTags = async (type?: string) => {
}
);

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const getService = async (id: string) => {
const response = await fetch(`${API_BASE_URL}/v1/services/${id}`, {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const createService = async (data: any) => {
Expand All @@ -76,13 +62,7 @@ export const createService = async (data: any) => {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const updateService = async (serviceId: string, data: any) => {
Expand All @@ -95,13 +75,7 @@ export const updateService = async (serviceId: string, data: any) => {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const deleteService = async (id: string) => {
Expand All @@ -110,8 +84,5 @@ export const deleteService = async (id: string) => {
credentials: "include",
});

if (!response.ok) {
const result = await response.json();
throw new Error(result.message);
}
await handleResponse(response);
};
31 changes: 5 additions & 26 deletions src/api/Team.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { API_BASE_URL } from "@/configs/Constant";
import { handleResponse } from "@/utils/Response";

export const getTeams = async (type?: string) => {
const queryParams = new URLSearchParams();
Expand All @@ -13,13 +14,7 @@ export const getTeams = async (type?: string) => {
}
);

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const updateTeamUsers = async (teamId: string, data: any) => {
Expand All @@ -32,13 +27,7 @@ export const updateTeamUsers = async (teamId: string, data: any) => {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const createTeam = async (data: any) => {
Expand All @@ -51,24 +40,14 @@ export const createTeam = async (data: any) => {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};


export const deleteTeam = async (id: string) => {
const response = await fetch(`${API_BASE_URL}/v1/teams/${id}`, {
method: "DELETE",
credentials: "include",
});

if (!response.ok) {
const result = await response.json();
throw new Error(result.message);
}
await handleResponse(response);
};
17 changes: 3 additions & 14 deletions src/api/User.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import { API_BASE_URL } from "@/configs/Constant";
import { handleResponse } from "@/utils/Response";

export const me = async () => {
const response = await fetch(`${API_BASE_URL}/v1/users/me`, {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};

export const getUsers = async () => {
const response = await fetch(`${API_BASE_URL}/v1/users`, {
credentials: "include",
});

const result = await response.json();

if (!response.ok) {
throw new Error(result.message);
}

return result.data;
return await handleResponse(response);
};
1 change: 1 addition & 0 deletions src/configs/Constant.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const APP_NAME = import.meta.env.VITE_APP_NAME;
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "http://localhost:3000";
export const MODE = import.meta.env.MODE;
4 changes: 2 additions & 2 deletions src/hooks/useServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const useServices = (
setServices(data.services);
setTotal(data.total);
setError(null);
} catch (e) {
} catch (error) {
setError("An error occurred while fetching services.");
console.error("An error occurred: ", e);
console.error("An error occurred: ", error);
} finally {
setIsLoading(false);
}
Expand Down
19 changes: 19 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import * as Sentry from "@sentry/react";
import App from "@/App";
import { MODE } from "@/configs/Constant";
import "./index.css";

Sentry.init({
dsn: "https://b0d9d202173ea633eb9addca5bce936f@o4507838470094848.ingest.us.sentry.io/4507838474354688",
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration(),
],
environment: MODE,
tracesSampleRate: 1.0,
tracePropagationTargets:
MODE === "production"
? ["localhost", /^https:\/\/api-serambi\.bpsbontang\.com/]
: ["localhost", /^https:\/\/staging-api-serambi\.bpsbontang\.com/],

replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0
});

createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
Expand Down
4 changes: 2 additions & 2 deletions src/pages/TeamPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const TeamPage = () => {
setIsLoading(true);
const data = await getTeams("all");
setTeams(data);
} catch (e) {
console.error("An error occurred: ", e);
} catch (error) {
console.error("An error occurred: ", error);
} finally {
setIsLoading(false);
}
Expand Down
20 changes: 20 additions & 0 deletions src/utils/Response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Sentry from "@sentry/react";

export const handleResponse = async (response: Response) => {
const result = await response.json();

if (!response.ok) {
const status = response.status;
const message = result.message || "An unknown error occurred";

if (!(status >= 400 && status < 500)) {
Sentry.captureException(new Error(message), {
extra: { result },
});
}

throw new Error(message);
}

return result.data;
};
Loading

0 comments on commit a03dc58

Please sign in to comment.