[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
0

Configure Feed

Select the types of activity you want to include in your feed.

feat(lzendpoint): Improved error handling

* Return error response when no sources found by request, or none configured
* try-catch and return well-formatted error response if source handling fails

FoxxMD (Jun 9, 2026, 1:42 PM UTC) da9edb21 d5c886d7

+15 -7
+15 -7
src/backend/server/endpointListenbrainzRoutes.ts
··· 11 11 import ScrobbleClients from '../scrobblers/ScrobbleClients.js'; 12 12 import { playToListenPayload } from '../common/vendor/listenbrainz/lzUtils.js'; 13 13 import { stringToDeterministicNumber } from '../utils/StringUtils.js'; 14 + import { messageWithCauses } from '../../core/ErrorUtils.js'; 14 15 15 16 const TEXT_WILDCARD_REGEX = new RegExp(/text\/.+/); 16 17 ··· 48 49 lzJsonParser, nonEmptyCheck, async function (req, res) { 49 50 webhookIngress.trackIngress(req, false); 50 51 51 - res.status(200).json({status: "ok"}); 52 + logger.trace({body: req.body}, "Recieved request Body"); 52 53 54 + const playerStates = playStateFromRequest(req.body); 53 55 54 56 const sources = scrobbleSources.getByType('endpointlz') as EndpointListenbrainzSource[]; 55 57 if (sources.length === 0) { 56 58 logger.warn('Received Listenbrainz endpoint payload but no Listenbrainz endpoint sources are configured'); 59 + return res.status(409).json({error: `Received Listenbrainz endpoint payload but no Listenbrainz endpoint sources are configured`, code: 409}); 57 60 } 58 61 59 62 const validSources = sources.filter(x => x.matchRequest(req)); 60 63 if (validSources.length === 0) { 61 64 const [slug, token] = parseDisplayIdentifiersFromRequest(req); 62 65 logger.warn(`No Listenbrainz endpoint config matched => Slug: ${slug} | Token: ${token}`); 66 + return res.status(409).json({error: `No Listenbrainz endpoint config matched => Slug: ${slug} | Token: ${token}`, code: 409}); 63 67 } 64 68 65 - if(isDebugMode()) { 66 - logger.debug({body: req.body}, "Recieved request Body"); 69 + try { 70 + for (const source of validSources) { 71 + await source.handle(playerStates); 72 + } 73 + } catch (e) { 74 + const submitListenError = new Error('Unexpected error occurred while processing submit-listens request', {cause: e}); 75 + const errMsg = messageWithCauses(submitListenError); 76 + logger.error(submitListenError); 77 + return res.status(500).json({error: errMsg, code: 500}); 67 78 } 68 - const playerStates = playStateFromRequest(req.body); 69 79 70 - for (const source of validSources) { 71 - await source.handle(playerStates); 72 - } 80 + return res.status(200).json({status: "ok"}); 73 81 }); 74 82 75 83 app.get('/1/user/:username/playing-now', async function (req, res) {