mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 12:36:57 +00:00
split exception logging from error logging to simplify and improve mastodon errors
This commit is contained in:
parent
f7ca7a2cc0
commit
282ef9e673
2 changed files with 42 additions and 49 deletions
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { getErrorData, getErrorStatus, MastodonLogger } from '@/server/api/mastodon/MastodonLogger.js';
|
||||
import { getErrorData, getErrorException, getErrorStatus, MastodonLogger } from '@/server/api/mastodon/MastodonLogger.js';
|
||||
import { MastodonClientService } from '@/server/api/mastodon/MastodonClientService.js';
|
||||
import { ApiAccountMastodon } from '@/server/api/mastodon/endpoints/account.js';
|
||||
import { ApiAppsMastodon } from '@/server/api/mastodon/endpoints/apps.js';
|
||||
|
@ -47,16 +47,20 @@ export class MastodonApiServerService {
|
|||
this.serverUtilityService.addFlattenedQueryType(fastify);
|
||||
|
||||
// Convert JS exceptions into error responses
|
||||
fastify.setErrorHandler((error, _, reply) => {
|
||||
fastify.setErrorHandler((error, request, reply) => {
|
||||
const data = getErrorData(error);
|
||||
const status = getErrorStatus(error);
|
||||
const exception = getErrorException(error);
|
||||
if (exception) {
|
||||
this.logger.exception(request, exception);
|
||||
}
|
||||
|
||||
reply.code(status).send(data);
|
||||
});
|
||||
|
||||
// Log error responses (including converted JSON exceptions)
|
||||
fastify.addHook('onSend', (request, reply, payload, done) => {
|
||||
if (reply.statusCode >= 500 || (reply.statusCode >= 400 && this.logger.verbose)) {
|
||||
if (reply.statusCode >= 400 && reply.statusCode <= 500) {
|
||||
if (typeof(payload) === 'string' && String(reply.getHeader('content-type')).toLowerCase().includes('application/json')) {
|
||||
const body = JSON.parse(payload);
|
||||
const data = getErrorData(body);
|
||||
|
|
|
@ -25,13 +25,29 @@ export class MastodonLogger {
|
|||
}
|
||||
|
||||
public error(request: FastifyRequest, error: MastodonError, status: number): void {
|
||||
const path = new URL(request.url, getBaseUrl(request)).pathname;
|
||||
const path = getPath(request);
|
||||
|
||||
if (status >= 400 && status <= 499) { // Client errors
|
||||
this.logger.debug(`Error in mastodon endpoint ${request.method} ${path}:`, error);
|
||||
} else { // Server errors
|
||||
this.logger.error(`Error in mastodon endpoint ${request.method} ${path}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
public exception(request: FastifyRequest, ex: Error): void {
|
||||
const path = getPath(request);
|
||||
|
||||
// Exceptions are always server errors, and should therefore always be logged.
|
||||
this.logger.error(`Error in mastodon endpoint ${request.method} ${path}:`, ex);
|
||||
}
|
||||
}
|
||||
|
||||
function getPath(request: FastifyRequest): string {
|
||||
try {
|
||||
return new URL(request.url, getBaseUrl(request)).pathname;
|
||||
} catch {
|
||||
return request.url;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move elsewhere
|
||||
|
@ -40,6 +56,17 @@ export interface MastodonError {
|
|||
error_description?: string;
|
||||
}
|
||||
|
||||
export function getErrorException(error: unknown): Error | null {
|
||||
if (error instanceof Error) {
|
||||
// Axios errors are not exceptions - they're from the remote
|
||||
if (!('response' in error) || !error.response || typeof (error.response) !== 'object') {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getErrorData(error: unknown): MastodonError {
|
||||
// Axios wraps errors from the backend
|
||||
error = unpackAxiosError(error);
|
||||
|
@ -78,7 +105,10 @@ export function getErrorData(error: unknown): MastodonError {
|
|||
}
|
||||
}
|
||||
|
||||
return convertUnknownError(error);
|
||||
return {
|
||||
error: 'INTERNAL_ERROR',
|
||||
error_description: 'Internal error occurred. Please contact us if the error persists.',
|
||||
};
|
||||
}
|
||||
|
||||
function unpackAxiosError(error: unknown): unknown {
|
||||
|
@ -101,66 +131,25 @@ function unpackAxiosError(error: unknown): unknown {
|
|||
}
|
||||
|
||||
function convertApiError(apiError: ApiError): MastodonError {
|
||||
const mastoError: MastodonError & Partial<ApiError> & { stack?: unknown, statusCode?: number } = {
|
||||
...apiError,
|
||||
return {
|
||||
error: apiError.code,
|
||||
error_description: apiError.message,
|
||||
};
|
||||
|
||||
delete mastoError.code;
|
||||
delete mastoError.stack;
|
||||
delete mastoError.message;
|
||||
delete mastoError.httpStatusCode;
|
||||
|
||||
return mastoError;
|
||||
}
|
||||
|
||||
function convertErrorMessageError(error: { error: string, message: string }): MastodonError {
|
||||
const mastoError: MastodonError & { stack?: unknown, message?: string, statusCode?: number } = {
|
||||
...error,
|
||||
return {
|
||||
error: error.error,
|
||||
error_description: error.message,
|
||||
};
|
||||
|
||||
delete mastoError.stack;
|
||||
delete mastoError.message;
|
||||
delete mastoError.statusCode;
|
||||
|
||||
return mastoError;
|
||||
}
|
||||
|
||||
function convertUnknownError(data: object = {}): MastodonError {
|
||||
const mastoError = Object.assign({}, data, {
|
||||
error: 'INTERNAL_ERROR',
|
||||
error_description: 'Internal error occurred. Please contact us if the error persists.',
|
||||
id: '5d37dbcb-891e-41ca-a3d6-e690c97775ac',
|
||||
kind: 'server',
|
||||
});
|
||||
|
||||
if ('statusCode' in mastoError) {
|
||||
delete mastoError.statusCode;
|
||||
}
|
||||
|
||||
if ('stack' in mastoError) {
|
||||
delete mastoError.stack;
|
||||
}
|
||||
|
||||
return mastoError;
|
||||
}
|
||||
|
||||
function convertGenericError(error: Error): MastodonError {
|
||||
const mastoError: MastodonError & Partial<Error> & { statusCode?: number } = {
|
||||
return {
|
||||
...error,
|
||||
error: 'INTERNAL_ERROR',
|
||||
error_description: String(error),
|
||||
};
|
||||
|
||||
delete mastoError.name;
|
||||
delete mastoError.message;
|
||||
delete mastoError.stack;
|
||||
delete mastoError.statusCode;
|
||||
|
||||
return mastoError;
|
||||
}
|
||||
|
||||
export function getErrorStatus(error: unknown): number {
|
||||
|
|
Loading…
Add table
Reference in a new issue