92 lines
3.2 KiB
TypeScript
92 lines
3.2 KiB
TypeScript
import type { Handle, HandleServerError } from '@sveltejs/kit';
|
|
import { createAuth } from '@sgse-app/backend/convex/auth';
|
|
import { getToken, createConvexHttpClient } from '@mmailaender/convex-better-auth-svelte/sveltekit';
|
|
import { api } from '@sgse-app/backend/convex/_generated/api';
|
|
|
|
export const handle: Handle = async ({ event, resolve }) => {
|
|
event.locals.token = await getToken(createAuth, event.cookies);
|
|
|
|
return resolve(event);
|
|
};
|
|
|
|
export const handleError: HandleServerError = async ({ error, event, status, message }) => {
|
|
// Notificar erros 404 e 500+ (erros internos do servidor)
|
|
if (status === 404 || status === 500 || status >= 500) {
|
|
// Evitar loop infinito: não registrar erros relacionados à própria página de erros
|
|
const urlPath = event.url.pathname;
|
|
if (urlPath.includes('/ti/erros-servidor')) {
|
|
console.warn(
|
|
`⚠️ Erro na página de erros do servidor (${status}): Não será registrado para evitar loop.`
|
|
);
|
|
} else {
|
|
try {
|
|
// Obter token do usuário (se autenticado)
|
|
const token = event.locals.token;
|
|
|
|
// Criar cliente Convex para chamar a action
|
|
const client = createConvexHttpClient({
|
|
token: token || undefined
|
|
});
|
|
|
|
// Extrair informações do erro
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
const url = event.url.toString();
|
|
const method = event.request.method;
|
|
const ipAddress = event.getClientAddress();
|
|
const userAgent = event.request.headers.get('user-agent') || undefined;
|
|
|
|
// Log para debug
|
|
console.log(`📝 Registrando erro ${status} no servidor:`, {
|
|
url,
|
|
method,
|
|
mensagem: errorMessage.substring(0, 100)
|
|
});
|
|
|
|
// Chamar action para registrar e notificar erro
|
|
// Aguardar a promise mas não bloquear a resposta se falhar
|
|
try {
|
|
// Usar Promise.race com timeout para evitar bloquear a resposta
|
|
const actionPromise = client.action(api.errosServidor.registrarErroServidor, {
|
|
statusCode: status,
|
|
mensagem: errorMessage,
|
|
stack: errorStack,
|
|
url,
|
|
method,
|
|
ipAddress,
|
|
userAgent,
|
|
usuarioId: undefined // Pode ser implementado depois para obter do token
|
|
});
|
|
|
|
// Timeout de 3 segundos
|
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
setTimeout(() => reject(new Error('Timeout ao registrar erro')), 3000);
|
|
});
|
|
|
|
const resultado = await Promise.race([actionPromise, timeoutPromise]);
|
|
console.log(`✅ Erro ${status} registrado com sucesso:`, resultado);
|
|
} catch (actionError) {
|
|
// Log do erro de notificação, mas não falhar a resposta
|
|
console.error(
|
|
`❌ Erro ao registrar notificação de erro ${status}:`,
|
|
actionError instanceof Error ? actionError.message : actionError
|
|
);
|
|
}
|
|
} catch (err) {
|
|
// Se falhar ao criar cliente ou chamar action, apenas logar
|
|
// Não queremos que falhas na notificação quebrem a resposta de erro
|
|
console.error(
|
|
`❌ Erro ao tentar notificar equipe técnica sobre erro ${status}:`,
|
|
err instanceof Error ? err.message : err
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Retornar mensagem de erro padrão
|
|
return {
|
|
message: message || 'Erro interno do servidor',
|
|
status
|
|
};
|
|
};
|