view models
This commit is contained in:
8
adapters/logging/ConsoleErrorReporter.ts
Normal file
8
adapters/logging/ConsoleErrorReporter.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { ErrorReporter } from "@core/shared/application";
|
||||
|
||||
export class ConsoleErrorReporter implements ErrorReporter {
|
||||
report(error: Error, context?: unknown): void {
|
||||
const timestamp = new Date().toISOString();
|
||||
console.error(`[${timestamp}] Error reported:`, error.message, { error, context });
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,26 @@
|
||||
import { Logger } from "@core/shared/application";
|
||||
|
||||
export class ConsoleLogger implements Logger {
|
||||
debug(message: string, ...args: any[]): void {
|
||||
console.debug(message, ...args);
|
||||
private formatMessage(level: string, message: string, context?: unknown): string {
|
||||
const timestamp = new Date().toISOString();
|
||||
const contextStr = context ? ` | ${JSON.stringify(context)}` : '';
|
||||
return `[${timestamp}] ${level.toUpperCase()}: ${message}${contextStr}`;
|
||||
}
|
||||
|
||||
info(message: string, ...args: any[]): void {
|
||||
console.info(message, ...args);
|
||||
debug(message: string, context?: unknown): void {
|
||||
console.debug(this.formatMessage('debug', message, context));
|
||||
}
|
||||
|
||||
warn(message: string, ...args: any[]): void {
|
||||
console.warn(message, ...args);
|
||||
info(message: string, context?: unknown): void {
|
||||
console.info(this.formatMessage('info', message, context));
|
||||
}
|
||||
|
||||
error(message: string, ...args: any[]): void {
|
||||
console.error(message, ...args);
|
||||
warn(message: string, context?: unknown): void {
|
||||
console.warn(this.formatMessage('warn', message, context));
|
||||
}
|
||||
|
||||
error(message: string, error?: Error, context?: unknown): void {
|
||||
const errorStr = error ? ` | Error: ${error.message}` : '';
|
||||
console.error(this.formatMessage('error', message, context) + errorStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,23 @@
|
||||
* error handling, and authentication.
|
||||
*/
|
||||
|
||||
import { Logger } from '../../interfaces/Logger';
|
||||
import { ErrorReporter } from '../../interfaces/ErrorReporter';
|
||||
|
||||
export class BaseApiClient {
|
||||
private baseUrl: string;
|
||||
private errorReporter: ErrorReporter;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(baseUrl: string) {
|
||||
constructor(baseUrl: string, errorReporter: ErrorReporter, logger: Logger) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.errorReporter = errorReporter;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
protected async request<T>(method: string, path: string, data?: object): Promise<T> {
|
||||
this.logger.info(`${method} ${path}`);
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
@@ -36,7 +45,9 @@ export class BaseApiClient {
|
||||
} catch {
|
||||
// Keep default error message
|
||||
}
|
||||
throw new Error(errorData.message || `API request failed with status ${response.status}`);
|
||||
const error = new Error(errorData.message || `API request failed with status ${response.status}`);
|
||||
this.errorReporter.report(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
const text = await response.text();
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { ErrorReporter } from '../../interfaces/ErrorReporter';
|
||||
|
||||
export class ConsoleErrorReporter implements ErrorReporter {
|
||||
report(error: Error, context?: unknown): void {
|
||||
const timestamp = new Date().toISOString();
|
||||
console.error(`[${timestamp}] Error reported:`, error.message, { error, context });
|
||||
}
|
||||
}
|
||||
26
apps/website/lib/infrastructure/logging/ConsoleLogger.ts
Normal file
26
apps/website/lib/infrastructure/logging/ConsoleLogger.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Logger } from '../../interfaces/Logger';
|
||||
|
||||
export class ConsoleLogger implements Logger {
|
||||
private formatMessage(level: string, message: string, context?: unknown): string {
|
||||
const timestamp = new Date().toISOString();
|
||||
const contextStr = context ? ` | ${JSON.stringify(context)}` : '';
|
||||
return `[${timestamp}] ${level.toUpperCase()}: ${message}${contextStr}`;
|
||||
}
|
||||
|
||||
debug(message: string, context?: unknown): void {
|
||||
console.debug(this.formatMessage('debug', message, context));
|
||||
}
|
||||
|
||||
info(message: string, context?: unknown): void {
|
||||
console.info(this.formatMessage('info', message, context));
|
||||
}
|
||||
|
||||
warn(message: string, context?: unknown): void {
|
||||
console.warn(this.formatMessage('warn', message, context));
|
||||
}
|
||||
|
||||
error(message: string, error?: Error, context?: unknown): void {
|
||||
const errorStr = error ? ` | Error: ${error.message}` : '';
|
||||
console.error(this.formatMessage('error', message, context) + errorStr);
|
||||
}
|
||||
}
|
||||
3
apps/website/lib/interfaces/ErrorReporter.ts
Normal file
3
apps/website/lib/interfaces/ErrorReporter.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface ErrorReporter {
|
||||
report(error: Error, context?: unknown): void;
|
||||
}
|
||||
6
apps/website/lib/interfaces/Logger.ts
Normal file
6
apps/website/lib/interfaces/Logger.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface Logger {
|
||||
debug(message: string, context?: unknown): void;
|
||||
info(message: string, context?: unknown): void;
|
||||
warn(message: string, context?: unknown): void;
|
||||
error(message: string, error?: Error, context?: unknown): void;
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import { PaymentsApiClient } from '../api/payments/PaymentsApiClient';
|
||||
import { AuthApiClient } from '../api/auth/AuthApiClient';
|
||||
import { AnalyticsApiClient } from '../api/analytics/AnalyticsApiClient';
|
||||
import { MediaApiClient } from '../api/media/MediaApiClient';
|
||||
import { ConsoleErrorReporter } from '../infrastructure/logging/ConsoleErrorReporter';
|
||||
import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';
|
||||
|
||||
// Services
|
||||
import { RaceService } from './races/RaceService';
|
||||
@@ -37,6 +39,9 @@ import { SessionService } from './auth/SessionService';
|
||||
* Services now directly instantiate View Models instead of using Presenters.
|
||||
*/
|
||||
export class ServiceFactory {
|
||||
private readonly errorReporter = new ConsoleErrorReporter();
|
||||
private readonly logger = new ConsoleLogger();
|
||||
|
||||
private readonly apiClients: {
|
||||
races: RacesApiClient;
|
||||
drivers: DriversApiClient;
|
||||
@@ -52,15 +57,15 @@ export class ServiceFactory {
|
||||
constructor(baseUrl: string) {
|
||||
// Initialize API clients
|
||||
this.apiClients = {
|
||||
races: new RacesApiClient(baseUrl),
|
||||
drivers: new DriversApiClient(baseUrl),
|
||||
teams: new TeamsApiClient(baseUrl),
|
||||
leagues: new LeaguesApiClient(baseUrl),
|
||||
sponsors: new SponsorsApiClient(baseUrl),
|
||||
payments: new PaymentsApiClient(baseUrl),
|
||||
auth: new AuthApiClient(baseUrl),
|
||||
analytics: new AnalyticsApiClient(baseUrl),
|
||||
media: new MediaApiClient(baseUrl),
|
||||
races: new RacesApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
drivers: new DriversApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
teams: new TeamsApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
leagues: new LeaguesApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
sponsors: new SponsorsApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
payments: new PaymentsApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
auth: new AuthApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
analytics: new AnalyticsApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
media: new MediaApiClient(baseUrl, this.errorReporter, this.logger),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
3
core/shared/application/ErrorReporter.ts
Normal file
3
core/shared/application/ErrorReporter.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface ErrorReporter {
|
||||
report(error: Error, context?: unknown): void;
|
||||
}
|
||||
Reference in New Issue
Block a user