0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00

refactor: report all errors and user id (#3580)

to ApplicationInsights for better error analyzing.
This commit is contained in:
Gao Sun 2023-03-22 19:35:18 +08:00 committed by GitHub
parent c8fdaa0441
commit 29be040668
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 17 deletions

View file

@ -1,7 +1,6 @@
import { appInsights } from '@logto/shared/app-insights';
import { tryThat } from '@silverhand/essentials';
import type { BaseContext, NextFunction } from '@withtyped/server';
import { RequestError } from '@withtyped/server';
/**
* Build a middleware function that reports error to Azure Application Insights.
@ -9,9 +8,7 @@ import { RequestError } from '@withtyped/server';
export default function withErrorReport<InputContext extends BaseContext>() {
return async (context: InputContext, next: NextFunction<InputContext>) => {
await tryThat(next(context), (error) => {
if (!(error instanceof RequestError && error.status < 500)) {
appInsights.trackException(error);
}
appInsights.trackException(error);
throw error;
});
};

View file

@ -3,6 +3,7 @@ import { useContext } from 'react';
import AppLoading from '@/components/AppLoading';
import { isCloud } from '@/consts/cloud';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import useTrackUserId from '@/hooks/use-track-user-id';
import OnboardingApp from '@/onboarding/App';
import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data';
import ConsoleApp from '@/pages/Main';
@ -11,6 +12,8 @@ function TenantAppContainer() {
const { userEndpoint } = useContext(AppEndpointsContext);
const { isOnboarding, isLoaded } = useUserOnboardingData();
useTrackUserId();
if (!userEndpoint || (isCloud && !isLoaded)) {
return <AppLoading />;
}

View file

@ -0,0 +1,42 @@
import { useLogto } from '@logto/react';
import { trySafe } from '@silverhand/essentials';
import { useEffect } from 'react';
import { getAppInsights } from '@/utils/app-insights';
class NoIdTokenClaimsError extends Error {
name = 'NoIdTokenClaimsError';
message = 'Cloud not fetch ID Token claims where user is authenticated.';
}
const useTrackUserId = () => {
const { isAuthenticated, getIdTokenClaims } = useLogto();
useEffect(() => {
const setUserId = async () => {
const appInsights = getAppInsights();
if (!appInsights) {
return;
}
if (!isAuthenticated) {
appInsights.clearAuthenticatedUserContext();
return;
}
const claims = await trySafe(getIdTokenClaims());
if (claims) {
appInsights.setAuthenticatedUserContext(claims.sub, claims.sub, true);
} else {
appInsights.trackException({ exception: new NoIdTokenClaimsError() });
}
};
void setUserId();
}, [getIdTokenClaims, isAuthenticated]);
};
export default useTrackUserId;

View file

@ -9,6 +9,8 @@ import { isCloud } from '@/consts/cloud';
let reactPlugin: Optional<ReactPlugin>;
let appInsights: Optional<ApplicationInsights>;
export const getAppInsights = () => appInsights;
const initAppInsights = () => {
// The string needs to be normalized since it may contain '"'
const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING?.replace(

View file

@ -37,12 +37,8 @@ export default async function initApp(app: Koa): Promise<void> {
}
const tenant = await trySafe(tenantPool.get(tenantId), (error) => {
if (error instanceof TenantNotFoundError) {
ctx.status = 404;
} else {
ctx.status = 500;
appInsights.trackException(error);
}
ctx.status = error instanceof TenantNotFoundError ? 404 : 500;
appInsights.trackException(error);
});
if (!tenant) {

View file

@ -19,20 +19,16 @@ export default function koaErrorHandler<StateT, ContextT, BodyT>(): Middleware<
console.error(error);
}
// Report all exceptions to ApplicationInsights
appInsights.trackException(error);
if (error instanceof RequestError) {
ctx.status = error.status;
ctx.body = error.body;
if (error.status >= 500) {
appInsights.trackException(error);
}
return;
}
// Report unhandled exceptions
appInsights.trackException(error);
// Koa will handle `HttpError` with a built-in manner.
if (error instanceof HttpError) {
return;