Merge remote-tracking branch 'origin/dev' into chore/login
# Conflicts: # backend/.env.example # backend/package.json # backend/src/app.ts # backend/src/routes/login.ts # backend/src/routes/student.ts # docker-compose.yml # frontend/src/App.vue # frontend/src/views/HomePage.vue # frontend/src/views/LoginPage.vue # package-lock.json
This commit is contained in:
		
						commit
						de0199de96
					
				
					 109 changed files with 3789 additions and 1727 deletions
				
			
		
							
								
								
									
										35
									
								
								backend/src/util/apiHelper.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								backend/src/util/apiHelper.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| import axios, { AxiosRequestConfig } from 'axios'; | ||||
| import { getLogger, Logger } from '../logging/initalize.js'; | ||||
| 
 | ||||
| const logger: Logger = getLogger(); | ||||
| 
 | ||||
| /** | ||||
|  * Utility function to fetch data from an API endpoint with error handling. | ||||
|  * Logs errors but does NOT throw exceptions to keep the system running. | ||||
|  * | ||||
|  * @param url The API endpoint to fetch from. | ||||
|  * @param description A short description of what is being fetched (for logging). | ||||
|  * @param params | ||||
|  * @returns The response data if successful, or null if an error occurs. | ||||
|  */ | ||||
| export async function fetchWithLogging<T>(url: string, description: string, params?: Record<string, any>): Promise<T | null> { | ||||
|     try { | ||||
|         const config: AxiosRequestConfig = params ? { params } : {}; | ||||
| 
 | ||||
|         const response = await axios.get<T>(url, config); | ||||
|         return response.data; | ||||
|     } catch (error: any) { | ||||
|         if (error.response) { | ||||
|             if (error.response.status === 404) { | ||||
|                 logger.debug(`❌ ERROR: ${description} not found (404) at "${url}".`); | ||||
|             } else { | ||||
|                 logger.debug( | ||||
|                     `❌ ERROR: Failed to fetch ${description}. Status: ${error.response.status} - ${error.response.statusText} (URL: "${url}")` | ||||
|                 ); | ||||
|             } | ||||
|         } else { | ||||
|             logger.debug(`❌ ERROR: Network or unexpected error when fetching ${description}:`, error.message); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|  | @ -49,9 +49,7 @@ export function getNumericEnvVar(envVar: EnvVar): number { | |||
|     const valueString = getEnvVar(envVar); | ||||
|     const value = parseInt(valueString); | ||||
|     if (isNaN(value)) { | ||||
|         throw new Error( | ||||
|             `Invalid value for environment variable ${envVar.key}: ${valueString}. Expected a number.` | ||||
|         ); | ||||
|         throw new Error(`Invalid value for environment variable ${envVar.key}: ${valueString}. Expected a number.`); | ||||
|     } else { | ||||
|         return value; | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										19
									
								
								backend/src/util/translationHelper.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								backend/src/util/translationHelper.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import yaml from 'js-yaml'; | ||||
| import { FALLBACK_LANG } from '../config.js'; | ||||
| import { getLogger, Logger } from '../logging/initalize.js'; | ||||
| 
 | ||||
| const logger: Logger = getLogger(); | ||||
| 
 | ||||
| export function loadTranslations<T>(language: string): T { | ||||
|     try { | ||||
|         const filePath = path.join(process.cwd(), '_i18n', `${language}.yml`); | ||||
|         const yamlFile = fs.readFileSync(filePath, 'utf8'); | ||||
|         return yaml.load(yamlFile) as T; | ||||
|     } catch (error) { | ||||
|         logger.warn(`Cannot load translation for ${language}, fallen back to dutch`, error); | ||||
|         const fallbackPath = path.join(process.cwd(), '_i18n', `${FALLBACK_LANG}.yml`); | ||||
|         return yaml.load(fs.readFileSync(fallbackPath, 'utf8')) as T; | ||||
|     } | ||||
| } | ||||
		Reference in a new issue
	
	 Gerald Schmittinger
						Gerald Schmittinger