Skip to content

Commit

Permalink
chore: Refactor session state code and improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
devondragon committed Jul 22, 2024
1 parent cdd6195 commit 2cf6c58
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 92 deletions.
78 changes: 39 additions & 39 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/session-state/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"devDependencies": {
"@cloudflare/workers-types": "^4.20240117.0",
"typescript": "^5.0.4",
"wrangler": "^3.63.1"
"wrangler": "^3.65.1"
},
"dependencies": {
"itty-router": "^5.0.17"
Expand Down
65 changes: 24 additions & 41 deletions packages/session-state/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,49 @@
/**
* Provides session management functionality within a Cloudflare Workers environment.
* This module defines methods for creating, retrieving, and deleting sessions,
* This module defines methods for creating, retrieving, updating, adding to, and deleting sessions,
* with each session identified by a unique session ID. Sessions are stored in a Cloudflare KV namespace.
*
* The `Env` interface represents the expected environment configuration,
* containing the `sessionstore` KVNamespace for session data storage.
*
* Functions:
* Functions (in the session.ts file) include:
* - `generateSessionId`: Generates a unique session identifier using `crypto.randomUUID`.
* - `createSession`: Creates a new session with the provided data in the Cloudflare KV store and returns the session ID.
* - `updateSession`: Updates the data for a given session ID in the Cloudflare KV store.
* - `addToSession`: Adds data to an existing session in the Cloudflare KV store.
* - `getSessionData`: Retrieves session data for a given session ID from the Cloudflare KV store.
* - `deleteSession`: Deletes a session from the Cloudflare KV store using the session ID.
*
* The default export is an async `fetch` function that handles HTTP requests to create, get, and delete sessions based on the request path.
* It is designed to be deployed as part of a Cloudflare Worker.
* The default export is an async `fetch` function that handles HTTP requests to create, get, update, add to, and delete sessions based on the request path.
* It uses `itty-router` to define the routes and handle the requests.
* The supported routes are:
* - POST `/create`: Creates a new session.
* - GET `/get/:sessionId`: Retrieves session data for the given session ID.
* - DELETE `/delete/:sessionId`: Deletes the session with the given session ID.
* - PUT `/update/:sessionId`: Updates the session data for the given session ID.
* - PATCH `/add/:sessionId`: Adds data to the existing session with the given session ID.
* - ALL `*`: Catches all other requests and returns a 404 response.
*
* It is designed to be deployed as part of a Cloudflare Worker.
*/
import { AutoRouter, IRequest } from 'itty-router';
import { Env } from './env';
import {
createSession,
getSessionData,
deleteSession,
} from './session';
handleCreateSession,
handleGetSessionData,
handleAddToSession,
handleUpdateSession,
handleDeleteSession
} from './handlers';

const router = AutoRouter<IRequest, [Env, ExecutionContext]>();

router
.post('/create', async (request, env, ctx) => {
try {
const requestData = await request.json();
const sessionId = await createSession(requestData, env);
return new Response(sessionId, { status: 201 });
} catch (error) {
return new Response('Failed to create session', { status: 500 });
}
})
.get('/get/:sessionId', async ({ params }, env) => {
try {
const { sessionId } = params;
const data = await getSessionData(sessionId, env);
if (!data) {
return new Response('Session not found', { status: 404 });
}
return new Response(JSON.stringify(data), { status: 200 });
} catch (error) {
return new Response('Failed to retrieve session', { status: 500 });
}
})
.delete('/delete/:sessionId', async ({ params }, env) => {
try {
const { sessionId } = params;
await deleteSession(sessionId, env);
return new Response('Session deleted', { status: 200 });
} catch (error) {
return new Response('Failed to delete session', { status: 500 });
}
})
.post('/create', (request, env) => handleCreateSession(request, env))
.get('/get/:sessionId', (request, env) => handleGetSessionData(request, env))
.delete('/delete/:sessionId', (request, env) => handleDeleteSession(request, env))
.put('/update/:sessionId', (request, env) => handleUpdateSession(request, env))
.patch('/add/:sessionId', (request, env) => handleAddToSession(request, env))
.all('*', () => new Response('Invalid request', { status: 404 }));

export default {
fetch: router.handle,
};
export default { ...router }; // Export the router
42 changes: 31 additions & 11 deletions packages/session-state/src/session.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Env } from './env';

// Constants for error messages
const ERROR_CREATING_SESSION = 'Failed to create session';
const ERROR_UPDATING_SESSION = 'Failed to update session';
const ERROR_DELETING_SESSION = 'Failed to delete session';

export function generateSessionId(): string {
return crypto.randomUUID();
}
Expand All @@ -8,37 +13,52 @@ export async function createSession(data: any, env: Env): Promise<string> {
const sessionId = generateSessionId();
try {
await env.sessionstore.put(sessionId, JSON.stringify(data));
return sessionId;
} catch (error) {
console.error("Error creating session: " + error);
throw new Error('Failed to create session');
console.error("Error creating session:", error);
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
throw new Error(`${ERROR_CREATING_SESSION}: ${errorMessage}`);
}
return sessionId;
}

export async function updateSession(sessionId: string, data: any, env: Env): Promise<void> {
try {
await env.sessionstore.put(sessionId, JSON.stringify(data));
} catch (error) {
console.error("Error updating session: " + error);
throw new Error('Failed to update session');
console.error("Error updating session:", error);
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
throw new Error(`${ERROR_UPDATING_SESSION}: ${errorMessage}`);
}
}

export async function addToSession(sessionId: string, data: any, env: Env): Promise<void> {
const sessionData = await getSessionData(sessionId, env);
await updateSession(sessionId, { ...sessionData, ...data }, env);
try {
const sessionData = await getSessionData(sessionId, env);
await updateSession(sessionId, { ...sessionData, ...data }, env);
} catch (error) {
console.error("Error adding to session:", error);
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
throw new Error(`${ERROR_UPDATING_SESSION}: ${errorMessage}`);
}
}

export async function getSessionData(sessionId: string, env: Env): Promise<any> {
const data = await env.sessionstore.get(sessionId);
return data ? JSON.parse(data) : null;
try {
const data = await env.sessionstore.get(sessionId);
return data ? JSON.parse(data) : null;
} catch (error) {
console.error("Error retrieving session data:", error);
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
throw new Error(`Failed to retrieve session data: ${errorMessage}`);
}
}

export async function deleteSession(sessionId: string, env: Env): Promise<void> {
try {
await env.sessionstore.delete(sessionId);
} catch (error) {
console.error("Error deleting session: " + error);
throw new Error('Failed to delete session');
console.error("Error deleting session:", error);
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
throw new Error(`${ERROR_DELETING_SESSION}: ${errorMessage}`);
}
}

0 comments on commit 2cf6c58

Please sign in to comment.