Unable to solve in NodeJS: 'TypeError: Converting circular structure to JSON'

Viewed 210

I have overtaken an internal software tool from a former employee at our company that is written in NodeJS and is connected to a salesforce shop system currently.

Unfortunately, I'm relatively new to NodeJS and my job currently is to connect the tool to a new shopware 6 (sw6) system and have all the functionality mapped to the new shop system which are for example creating job postings on the shop system.

I have checked and established a connection to the sw6 in an isolated manner but I'm failing to have a job posted on the sw6 system end-2-end, beginning from the Jobposting form in the internal software tool to having a landingpage in the shop system for the created job.

I may share you the code of the function that I'm trying to adjust:

exports.postNewJob = function(req, res) {
    var jobOffer = {
        active              : true,
        UserId              : req.user.id,
        jobId               : req.body.jobName + "-" + req.body.marketId + "-" + req.body.jobType,
        jobTitle            : jobMapper.mapJobId(req.body.jobName) + jobMapper.mapJobType(req.body.jobType),
        storeId             : req.body.marketId,
        storeLocation       : req.body.marketName,
        jobType             : req.body.jobType,
        hoursWeek           : req.body.workingHours_Week? req.body.workingHours_Week : null,
        hoursMonth          : req.body.workingHours_Month? req.body.workingHours_Month : null,
        christmasBonus      : req.body.christmasBonus? true : false,
        holidayPay          : req.body.holidayPay? true : false,
        employeeDiscount    : req.body.employeeDiscount? true: false,
        freeDrinks          : req.body.freeDrinks? true : false,
        bav                 : req.body.bav? true : false,
        vwl                 : req.body.vwl? true : false,
        vacationAmount      : req.body.vacation,
        otherBenefits       : req.body.otherBenefits,
        contactMail         : req.body.contactEmail,
        contactPartner      : req.body.contactName,
        contactMarket       : req.body.contactPlace,
        contactStreet       : req.body.contactStreet + " ",
        contactStreetNumber : req.body.contactStreetNumber,
        contactZipCode      : req.body.contactPLZ + " ",
        contactCity         : req.body.contactCity,
        countryCode         : req.body.site,
        author              : req.user.emailAdress,
        hrLink              : req.body.hrLink,
        promoted            : false,
        promotionValue      : "",
        promotionBillingAdress : req.body.premiumBillingAdress
    };
    var premium = req.body.premium;
    var premiumLimit = req.body.premiumLimit;
    var premiumBillingAdress = req.body.premiumBillingAdress;
    var jobName = req.body.jobName;

           models.JobType.findAll()
            .then(function(jobTypes) {
                models.JobPostingsMarket.findOrCreate({ where: {jobId: jobOffer.jobId}, defaults: jobOffer})
                    .then(function(jobPosting){
                        console.log("Saved new job posting with following job id: " + jobOffer.jobId);
    
                        shopwareAuth.getToken(config.CLIENT_ID_SW, config.CLIENT_PASSWORD_SW, config.SHOPWARE_INSTANCE, req.user.emailAdress, req.session, function(err, accessToken){
                            if(err) {
                                console.error("ERROR: Could not authenticate with shopware. Error: " + err);
                                res.render('app/market/jobs/form', {createError : true, jobOffer, jobName : jobName, premium : premium, premiumLimit : premiumLimit, premiumBillingAdress : premiumBillingAdress, user : req.user, jobTypes : jobTypes});
                            } else {
                                var requestBody = {
                                    'id': md5(jobOffer.jobId),
                                    'name': jobOffer.storeId + " - " + jobOffer.jobTitle,
                                    'url': jobOffer.jobId,
                                    'active': true,
                                    'salesChannels':[{'id':'XXX'}],
                                    'cmsPageId': 'XXX'
                                };
                                var headers = {
                                    'Authorization': 'Bearer ' + accessToken,
                                    'Content-Type': 'application/json',
                                };    
                                const options = {
                                    url: config.SHOPWARE_INSTANCE + '/api/landing-page/',
                                    method: 'POST',
                                    headers: headers,
                                    data: requestBody                 
                                };
    
                                console.log(options);
                                
                                axios.request(options)
                                    .then(response => {
                                        console.log("Created new Job Landing Page with ID: " + jobOffer.jobId)
                                        console.log(response.data);
                                    }) 
                                    .catch(err => {
                                        console.error('ERROR: An error occurred while sending data to shopware: ');
                                        console.error(err);
                                        res.render('app/market/jobs/form', {createError : true, jobOffer, jobName, premium, premiumLimit, premiumBillingAdress, user : req.user, jobTypes : jobTypes});
                                    })
                                    .then(() => {
            
                                        console.log({createJob : true, user : req.user, jobTypes : jobTypes});
                                        res.render('app/market/jobs/form', {createJob : true, user : req.user, jobTypes : jobTypes});         
                                    })
                                    .catch(err => {
                                        console.error(err.response.data);
                                        res.render('app/market/jobs/form', {createError : true, jobOffer, jobName, premium, premiumLimit, premiumBillingAdress, user : req.user, jobTypes : jobTypes});
                                    });
                                }
                            });
                        })
                    .catch(err=>{
                        console.error("ERROR: An error occurred while saving the new job posting to MariaDB: " + err);
                        res.render('app/market/jobs/form', {createError : true, jobOffer, jobName, premium, premiumLimit, premiumBillingAdress, user : req.user, jobTypes : jobTypes});                        
                    });
                })    
                .catch(err=>{
                    console.error("ERROR: An error occurred while loading job types on new job page.")
                    console.error(err);
                    res.redirect('/error');
                });
    }

When I'm trying to create a Job, I get the following error:

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'ClientRequest'
    |     property 'socket' -> object with constructor 'TLSSocket'
    --- property '_httpMessage' closes the circle
    at JSON.stringify (<anonymous>)
    at hash (C:\Users\Klat\TOOL\TOOL\node_modules\express-session\index.js:594:18)
    at isSaved (C:\Users\Klat\TOOL\TOOL\node_modules\express-session\index.js:427:54)
    at shouldSave (C:\Users\Klat\TOOL\TOOL\node_modules\express-session\index.js:445:12)
    at ServerResponse.end (C:\Users\Klat\TOOL\TOOL\node_modules\express-session\index.js:330:11)
    at Gzip.onStreamEnd (C:\Users\Klat\TOOL\TOOL\node_modules\compression\index.js:212:14)
    at Gzip.emit (events.js:400:28)
    at endReadableNT (internal/streams/readable.js:1317:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)

I have tried a lot of stuff in order to debug this error but I have a hard time understanding what the problem is and at which point exactly the error gets raised.

I hope that the information delivered is sufficient for you to understand my problem. Thanks a lot!

1 Answers

Luckily, I was able to find the problem just right now with some inspiration from this Post here: TypeError: circular structure to JSON starting at object with constructor 'ClientRequest' property 'socket' -> object with constructor 'Socket'

In the function for requesting the sw6 access token (shopwareAuth.getToken), which I had already adapted from the old salesforce token request function, I made use of the complete response from the OAuth2 query response which was wrong as only the res.data part was needed.

Related