{/* ... */}
+const ExpensiveComponent = React.memo(({data}: { data: UserProfile }) => {
+ // Expensive rendering logic
+ return {/* ... */} < /div>
})
```
@@ -37,15 +38,15 @@ const handleClick = useCallback(() => {
// Use react-window or similar libraries for large data sets
import {FixedSizeList as List} from 'react-window'
-const VirtualizedList = ({items}: {items: Profile[]}) => (
-
+const VirtualizedList = ({items}: { items: Profile[] }) => (
+
{Row}
-
+ < /List>
)
```
@@ -92,12 +93,13 @@ yarn build && npx webpack-bundle-analyzer .next/static/chunks
import Image from 'next/image'
```
@@ -105,10 +107,16 @@ import Image from 'next/image'
```typescript
```
@@ -216,6 +224,7 @@ const profileSummary = await pg.one(
```typescript
// In Express configuration
import compression from 'compression'
+
app.use(compression())
```
@@ -239,6 +248,7 @@ export const rateLimitedHandler: APIHandler<'expensive-endpoint'> = withRateLimi
```typescript
import redis from 'redis'
+
const client = redis.createClient()
async function getCachedProfile(userId: string) {
@@ -354,7 +364,7 @@ pool.connectionTimeoutMillis = 10000 // Timeout for acquiring connection
```typescript
// Proper error handling for connection pool issues
if (error.message && error.message.includes('MaxClientsInSessionMode')) {
- throw new APIError(503, 'Service temporarily unavailable due to high demand')
+ throw APIErrors.serviceUnavailable('Service temporarily unavailable due to high demand')
}
```
@@ -507,16 +517,16 @@ export default async function handler(req: Request) {
```yaml
# terraform configuration for load balancer
-resource "google_compute_backend_service" "api_backend" {
- name = "api-backend"
- protocol = "HTTP"
- timeout_sec = 30
+ resource "google_compute_backend_service" "api_backend" {
+ name = "api-backend"
+ protocol = "HTTP"
+ timeout_sec = 30
# Health checks
- health_checks = [google_compute_health_check.api.self_link]
+ health_checks = [google_compute_health_check.api.self_link]
# Load balancing algorithm
- balancing_mode = "UTILIZATION"
+ balancing_mode = "UTILIZATION"
}
```
diff --git a/web/lib/api.ts b/web/lib/api.ts
index 0b965ab0..1b5f3614 100644
--- a/web/lib/api.ts
+++ b/web/lib/api.ts
@@ -1,5 +1,6 @@
+import * as Sentry from '@sentry/nextjs'
import {API, APIParams, APIPath} from 'common/api/schema'
-import {APIError} from 'common/api/utils'
+import {APIErrors} from 'common/api/utils'
import {debug} from 'common/logger'
import {typedAPICall} from 'common/util/api'
import {sleep} from 'common/util/time'
@@ -15,19 +16,20 @@ export async function api(path: P, params: APIParams
= {})
if (auth.currentUser === null) {
// User is definitely not logged in
console.error(`api('${path}') called while unauthenticated`)
- throw new APIError(401, 'Not authenticated')
+ throw APIErrors.unauthorized('Not authenticated')
}
}
} catch (e) {
// Remove try / catch once all hooks/components are fixed
console.error('Need to fix this before removing try / catch', e)
+ Sentry.logger.error('Need to fix this before removing try / catch' + String(e))
let i = 0
while (!auth.currentUser) {
i++
await sleep(i * 500)
if (i > 5) {
console.error('User did not load after 5 iterations')
- throw new APIError(401, 'Not authenticated')
+ throw APIErrors.unauthorized('Not authenticated')
}
}
}