diff --git a/server/controllers/bots.ts b/server/controllers/bots.ts
index 2a8d6863a..a5ce1d79f 100644
--- a/server/controllers/bots.ts
+++ b/server/controllers/bots.ts
@@ -1,7 +1,8 @@
import { getServerActor } from '@server/models/application/application'
+import { logger } from '@uploadx/core'
import express from 'express'
import { truncate } from 'lodash'
-import { SitemapStream, streamToPromise } from 'sitemap'
+import { SitemapStream, streamToPromise, ErrorLevel } from 'sitemap'
import { buildNSFWFilter } from '../helpers/express-utils'
import { ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants'
import { asyncMiddleware } from '../middlewares'
@@ -34,7 +35,18 @@ async function getSitemap (req: express.Request, res: express.Response) {
urls = urls.concat(await getSitemapVideoChannelUrls())
urls = urls.concat(await getSitemapAccountUrls())
- const sitemapStream = new SitemapStream({ hostname: WEBSERVER.URL })
+ const sitemapStream = new SitemapStream({
+ hostname: WEBSERVER.URL,
+ errorHandler: (err: Error, level: ErrorLevel) => {
+ if (level === 'warn') {
+ logger.warn('Warning in sitemap generation.', { err })
+ } else if (level === 'throw') {
+ logger.error('Error in sitemap generation.', { err })
+
+ throw err
+ }
+ }
+ })
for (const urlObj of urls) {
sitemapStream.write(urlObj)
@@ -83,7 +95,8 @@ async function getSitemapLocalVideoUrls () {
url: WEBSERVER.URL + v.getWatchStaticPath(),
video: [
{
- title: v.name,
+ // Sitemap title should be < 100 characters
+ title: truncate(v.name, { length: 100, omission: '...' }),
// Sitemap description should be < 2000 characters
description: truncate(v.description || v.name, { length: 2000, omission: '...' }),
player_loc: WEBSERVER.URL + v.getEmbedStaticPath(),
diff --git a/server/tests/api/notifications/moderation-notifications.ts b/server/tests/api/notifications/moderation-notifications.ts
index ad991210e..d8a7d576e 100644
--- a/server/tests/api/notifications/moderation-notifications.ts
+++ b/server/tests/api/notifications/moderation-notifications.ts
@@ -601,7 +601,7 @@ describe('Test moderation notifications', function () {
})
it('Should not send a notification to moderators on new video without auto-blacklist', async function () {
- this.timeout(60000)
+ this.timeout(120000)
const name = 'video without auto-blacklist ' + buildUUID()
diff --git a/server/tests/misc-endpoints.ts b/server/tests/misc-endpoints.ts
index 9e404b549..663ac044a 100644
--- a/server/tests/misc-endpoints.ts
+++ b/server/tests/misc-endpoints.ts
@@ -3,6 +3,7 @@
import { expect } from 'chai'
import { cleanupTests, createSingleServer, makeGetRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
import { HttpStatusCode, VideoPrivacy } from '@shared/models'
+import { expectLogDoesNotContain } from './shared'
describe('Test misc endpoints', function () {
let server: PeerTubeServer
@@ -183,6 +184,23 @@ describe('Test misc endpoints', function () {
expect(res.text).to.contain('http://localhost:' + server.port + '/accounts/user1')
expect(res.text).to.contain('http://localhost:' + server.port + '/accounts/user2')
})
+
+ it('Should not fail with big title/description videos', async function () {
+ const name = 'v'.repeat(115)
+
+ await server.videos.upload({ attributes: { name, description: 'd'.repeat(2500), nsfw: false } })
+
+ const res = await makeGetRequest({
+ url: server.url,
+ path: '/sitemap.xml?t=2', // avoid using cache
+ expectedStatus: HttpStatusCode.OK_200
+ })
+
+ await expectLogDoesNotContain(server, 'Warning in sitemap generation')
+ await expectLogDoesNotContain(server, 'Error in sitemap generation')
+
+ expect(res.text).to.contain(`${'v'.repeat(97)}...`)
+ })
})
after(async function () {