fix: api helper voor extra error checks bij fetch dwengo api + schrijffout in controllers/themes

This commit is contained in:
Gabriellvl 2025-03-01 15:15:04 +01:00
parent 0c7f5791ea
commit 91eb374b7e
5 changed files with 45 additions and 8 deletions

View file

@ -17,7 +17,7 @@ function loadTranslations(language: string): Translations {
return yaml.load(yamlFile) as Translations;
} catch (error) {
console.error(
`Cant load for language: ${language}, fallen back on dutch`
`Cannot load translation for: ${language}, fallen back to Dutch`
);
console.error(error);
const fallbackPath = path.join(process.cwd(), '_i18n', 'nl.yml');

View file

@ -3,9 +3,12 @@ import { getAllLearningObjects } from '../controllers/learningObjects.js';
const router = express.Router();
// DWENGO learning objects
// Arg: hruid learningPath
// Query: language
// Route to fetch list of learning objects based on hruid of learning path
// example: http://localhost:3000/learningObject/un_artificiele_intelligentie
router.get('/:hruid', getAllLearningObjects);
export default router;

View file

@ -8,6 +8,8 @@ import {
const router = express.Router();
// DWENGO learning paths
// Query: hruids(list), language
// Route to fetch learning paths based on a list of HRUIDs
// Example: http://localhost:3000/learningPath?hruids=pn_werking&hruids=art1

View file

@ -1,5 +1,6 @@
import axios from 'axios';
import { DWENGO_API_BASE } from '../config/config.js';
import { fetchWithLogging } from "../util/apiHelper.js";
interface LearningObjectNode {
_id: string;
@ -18,7 +19,7 @@ function filterLearningObjectMetadata(data: any, htmlUrl: string) {
title: data.title,
htmlUrl,
// Html content object
// Url to fetch html content
language: data.language,
difficulty: data.difficulty,
estimatedTime: data.estimated_time,
@ -50,15 +51,18 @@ export async function getLearningObjectsFromPath(
) {
try {
const learningPathUrl = `${DWENGO_API_BASE}/learningPath/${hruid}/${language}`;
const learningPathResponse = await axios.get(learningPathUrl);
const nodes = learningPathResponse.data.nodes;
const learningPathData = await fetchWithLogging<{ nodes: LearningObjectNode[] }>(
learningPathUrl,
`Learning path for HRUID "${hruid}" in language "${language}"`
);
if (!nodes || nodes.length === 0) {
throw new Error('No learning objects found in this learning path.');
if (!learningPathData || !learningPathData.nodes || learningPathData.nodes.length === 0) {
console.error(`⚠️ WARNING: Learning path "${hruid}" exists but contains no learning objects.`);
return [];
}
return await Promise.all(
nodes.map(async (node: LearningObjectNode) => {
learningPathData.nodes.map(async (node: LearningObjectNode) => {
const metadataUrl = `${DWENGO_API_BASE}/learningObject/getMetadata?hruid=${node.learningobject_hruid}&version=${node.version}&language=${language}`;
const metadataResponse = await axios.get(metadataUrl);
@ -72,6 +76,5 @@ export async function getLearningObjectsFromPath(
);
} catch (error) {
console.error('Error fetching learning objects:', error);
throw new Error('Failed to fetch learning objects.');
}
}

View file

@ -0,0 +1,29 @@
import axios from 'axios';
// !!!! when logger is done -> change
/**
* 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).
* @returns The response data if successful, or null if an error occurs.
*/
export async function fetchWithLogging<T>(url: string, description: string): Promise<T | null> {
try {
const response = await axios.get<T>(url);
return response.data;
} catch (error: any) {
if (error.response) {
if (error.response.status === 404) {
console.error(`❌ ERROR: ${description} not found (404) at "${url}".`);
} else {
console.error(`❌ ERROR: Failed to fetch ${description}. Status: ${error.response.status} - ${error.response.statusText} (URL: "${url}")`);
}
} else {
console.error(`❌ ERROR: Network or unexpected error when fetching ${description}:`, error.message);
}
return null;
}
}