diff --git a/app/api/preserve/specs/preserve.spec.ts b/app/api/preserve/specs/preserve.spec.ts index 28a1769f82..3dfbd0168a 100644 --- a/app/api/preserve/specs/preserve.spec.ts +++ b/app/api/preserve/specs/preserve.spec.ts @@ -73,7 +73,7 @@ describe('Preserve', () => { ]; await testingEnvironment.setUp({ ...fixtures, settings: newSettings }, 'preserve-index'); - await expect(Preserve.setup('en', { _id: 'someid' })).rejects.toEqual({ + await expect(Preserve.setup('en', { _id: 'someid' })).rejects.toMatchObject({ message: 'Preserve configuration not found', code: 402, }); diff --git a/app/api/templates/specs/templates.spec.js b/app/api/templates/specs/templates.spec.js index bce97c9c96..d18ba12f6c 100644 --- a/app/api/templates/specs/templates.spec.js +++ b/app/api/templates/specs/templates.spec.js @@ -206,7 +206,7 @@ describe('templates', () => { await templates.save(changedTemplate); throw new Error('properties have swaped names, should have failed with an error'); } catch (error) { - expect(error).toEqual({ code: 400, message: "Properties can't swap names: text" }); + expect(error).toMatchObject({ code: 400, message: "Properties can't swap names: text" }); } }); diff --git a/app/api/users/specs/users.spec.js b/app/api/users/specs/users.spec.js index 7daaed279a..b6e81ae9d8 100644 --- a/app/api/users/specs/users.spec.js +++ b/app/api/users/specs/users.spec.js @@ -121,7 +121,7 @@ describe('Users', () => { _id: userId.toString(), username: 'user name', }; - await expect(users.save(userdata, currentUser)).rejects.toEqual({ + await expect(users.save(userdata, currentUser)).rejects.toMatchObject({ code: 400, message: 'Usernames can not contain spaces.', }); @@ -259,7 +259,7 @@ describe('Users', () => { role: 'editor', groups: [], }; - await expect(users.newUser(userdata, domain)).rejects.toEqual({ + await expect(users.newUser(userdata, domain)).rejects.toMatchObject({ code: 400, message: 'Usernames can not contain spaces.', }); diff --git a/app/api/utils/Error.js b/app/api/utils/Error.js index 045d718693..3fb74d8e01 100644 --- a/app/api/utils/Error.js +++ b/app/api/utils/Error.js @@ -1,11 +1,18 @@ -export default function (message, code = 500) { +/** + * @deprecated + */ +export default function (message, code = 500, logLevel = 'debug') { + if (code === 500) { + logLevel = 'error'; + } + if (message.ajv) { - return { message: message.message, ...message, code }; + return { message: message.message, ...message, code, logLevel }; } if (message instanceof Error) { - return { message: message.message, stack: message.stack, code, original: message }; + return { message: message.message, stack: message.stack, code, original: message, logLevel }; } - return { message, code }; + return { message, code, logLevel }; } diff --git a/app/api/utils/handleError.js b/app/api/utils/handleError.js index fa4750f183..38a8259773 100644 --- a/app/api/utils/handleError.js +++ b/app/api/utils/handleError.js @@ -4,6 +4,7 @@ import { createError } from 'api/utils/index'; import { appContext } from 'api/utils/AppContext'; import { UnauthorizedError } from 'api/authorization.v2/errors/UnauthorizedError'; import { ValidationError } from 'api/common.v2/validation/ValidationError'; +import { FileNotFound } from 'api/files/FileNotFound'; const ajvPrettifier = error => { const errorMessage = [error.message]; @@ -58,39 +59,53 @@ const prettifyError = (error, { req = {}, uncaught = false } = {}) => { let result = error; if (error instanceof Error) { - result = { code: 500, message: error.stack }; + result = { code: 500, message: error.stack, logLevel: 'error' }; } if (error instanceof Ajv.ValidationError) { - result = { code: 422, message: error.message, validations: error.errors }; + result = { code: 422, message: error.message, validations: error.errors, logLevel: 'debug' }; } if (error.name === 'ValidationError') { - result = { code: 422, message: error.message, validations: error.properties }; + result = { + code: 422, + message: error.message, + validations: error.properties, + logLevel: 'debug', + }; } if (error instanceof ValidationError) { - result = { code: 422, message: error.message, validations: error.errors }; + result = { code: 422, message: error.message, validations: error.errors, logLevel: 'debug' }; } if (error instanceof UnauthorizedError) { - result = { code: 401, message: error.message }; + result = { code: 401, message: error.message, logLevel: 'debug' }; + } + + if (error instanceof FileNotFound) { + result = { code: 404, message: error.message, logLevel: 'debug' }; } if (error.name === 'MongoError') { result.code = 500; + result.logLevel = 'error'; } if (error.message && error.message.match(/Cast to ObjectId failed for value/)) { result.code = 400; + result.logLevel = 'debug'; } if (error.message && error.message.match(/rison decoder error/)) { result.code = 400; + result.logLevel = 'debug'; } if (uncaught) { result.message = `uncaught exception or unhandled rejection, Node process finished !!\n ${result.message}`; + result.logLevel = 'error'; + result.code = 500; } const obfuscatedRequest = obfuscateCredentials(req); @@ -119,11 +134,12 @@ const getErrorMessage = (data, error) => { const sendLog = (data, error, errorOptions) => { const messageToLog = getErrorMessage(data, error); - if (data.code === 500) { - legacyLogger.error(messageToLog, errorOptions); - } else if (data.code === 400) { + if (data.logLevel === 'debug') { legacyLogger.debug(messageToLog, errorOptions); + return; } + + legacyLogger.error(messageToLog, errorOptions); }; function setRequestId(result) { diff --git a/app/api/utils/specs/__snapshots__/handleError.spec.js.snap b/app/api/utils/specs/__snapshots__/handleError.spec.js.snap index b52d62ba99..6fb41686ef 100644 --- a/app/api/utils/specs/__snapshots__/handleError.spec.js.snap +++ b/app/api/utils/specs/__snapshots__/handleError.spec.js.snap @@ -3,6 +3,7 @@ exports[`handleError errors by type when error is created with createError should return the error 1`] = ` Object { "code": 400, + "logLevel": "debug", "message": "test error", "prettyMessage": " test error", diff --git a/package.json b/package.json index 4f2fca289c..6bd5029778 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uwazi", - "version": "1.185.0-rc3", + "version": "1.185.0-rc4", "description": "Uwazi is a free, open-source solution for organising, analysing and publishing your documents.", "keywords": [ "react" @@ -111,7 +111,7 @@ "@huridocs/react-text-selection-handler": "^0.3.0", "@loadable/component": "^5.16.4", "@popperjs/core": "^2.11.8", - "@remix-run/router": "^1.19.2", + "@remix-run/router": "^1.16.1", "@sentry/node": "^7.114.0", "@sentry/react": "7.114.0", "@sentry/tracing": "^7.114.0", @@ -119,7 +119,7 @@ "@socket.io/redis-adapter": "7.2.0", "@socket.io/redis-emitter": "5.1.0", "@supercharge/promise-pool": "^3.2.0", - "@tanstack/react-table": "^8.20.5", + "@tanstack/react-table": "^8.19.3", "@types/franc": "^5.0.1", "@types/lodash": "^4.14.170", "@types/mime-types": "^2.1.1", @@ -147,11 +147,11 @@ "date-fns": "^3.6.0", "diacritics": "^1.3.0", "dotenv": "^16.4.5", - "express": "^4.20.0", - "express-http-proxy": "^2.1.1", + "express": "^4.19.2", + "express-http-proxy": "^2.0.0", "express-prom-bundle": "^7.0.0", "express-session": "1.18.0", - "filesize": "^10.1.6", + "filesize": "^10.1.4", "flag-icon-css": "^4.1.7", "flowbite": "^2.3.0", "flowbite-datepicker": "^1.2.7", @@ -165,7 +165,7 @@ "immutable": "^3.7.6", "is-reachable": "^5.2.1", "isomorphic-fetch": "3.0.0", - "jotai": "^2.9.3", + "jotai": "^2.9.1", "json-schema": "^0.4.0", "json-schema-to-typescript": "^13.1.2", "jvent": "1.0.2", @@ -173,7 +173,7 @@ "leaflet.gridlayer.googlemutant": "^0.14.1", "leaflet.markercluster": "^1.5.3", "lodash": "^4.17.21", - "luxon": "^3.5.0", + "luxon": "^3.4.4", "mark.js": "^8.11.1", "markdown-it": "14.1.0", "markdown-it-container": "4.0.0", @@ -191,12 +191,12 @@ "otplib": "^11.0.1", "passport": "^0.7.0", "passport-local": "^1.0.0", - "pdfjs-dist": "^4.6.82", + "pdfjs-dist": "^4.5.136", "postcss-loader": "^8.1.1", "postcss-prefix-selector": "^1.16.1", "prom-client": "^15.1.3", "prop-types": "^15.8.1", - "qrcode.react": "^4.0.1", + "qrcode.react": "^3.1.0", "qs": "^6.13.0", "react": "^18.3.1", "react-color": "^2.19.3", @@ -217,7 +217,7 @@ "react-redux": "5.0.6", "react-redux-form": "^1.16.14", "react-render-if-visible": "^2.1.1", - "react-router-dom": "6.26.2", + "react-router-dom": "6.23.1", "react-table": "^7.8.0", "react-table-sticky": "^1.1.3", "react-tabs": "^6.0.2", @@ -243,7 +243,7 @@ "superagent": "10.1.0", "svg-captcha": "^1.4.0", "tiny-cookie": "^2.5.1", - "typescript": "5.6.2", + "typescript": "5.5.4", "underscore": "^1.13.7", "url-join": "^4.0.1", "world-countries": "5.0.0", @@ -286,7 +286,7 @@ "@storybook/react": "^8.1.11", "@storybook/react-webpack5": "^8.1.11", "@storybook/test": "^8.1.11", - "@testing-library/jest-dom": "^6.5.0", + "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^15.0.7", "@testing-library/user-event": "^14.5.2", "@types/body-parser": "^1.19.2", @@ -296,7 +296,7 @@ "@types/enzyme": "3.10.12", "@types/enzyme-adapter-react-16": "1.0.2", "@types/expect-puppeteer": "4.4.7", - "@types/express": "4.17.21", + "@types/express": "4.17.13", "@types/express-session": "1.18.0", "@types/google.maps": "^3.48.2", "@types/immutable": "^3.8.7", @@ -343,7 +343,7 @@ "copy-webpack-plugin": "12.0.2", "css-loader": "^7.1.2", "css-minimizer-webpack-plugin": "^7.0.0", - "cypress": "13.14.2", + "cypress": "13.13.2", "cypress-axe": "^1.5.0", "cypress-plugin-snapshots": "^1.4.4", "cypress-real-events": "^1.13.0", @@ -358,7 +358,7 @@ "eslint-plugin-jsx-a11y": "6.7.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "5.1.3", - "eslint-plugin-react": "v7.36.1", + "eslint-plugin-react": "v7.34.3", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-storybook": "^0.8.0", "fetch-mock": "^9.11.0", @@ -376,19 +376,19 @@ "node-polyfill-webpack-plugin": "^4.0.0", "nodemon": "^3.1.4", "plop": "^4.0.1", - "postcss": "^8.4.45", - "prettier": "3.3.3", + "postcss": "^8.4.41", + "prettier": "3.2.5", "puppeteer": "^13.5.2", "react-dnd-test-backend": "15.1.1", "redux-mock-store": "^1.5.4", "rtlcss-webpack-plugin": "4.0.7", - "sass": "^1.78.0", + "sass": "^1.77.8", "sass-loader": "16.0.1", "storybook": "^8.1.11", "stream-mock": "^2.0.5", "supertest": "7.0.0", "svg-inline-loader": "^0.8.2", - "tailwindcss": "^3.4.10", + "tailwindcss": "^3.4.1", "terser-webpack-plugin": "^5.3.10", "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0",