DEV Community

Discussion on: Error: [nodemon] app crashed - waiting for file changes before starting...

Collapse
garretharp profile image
Garret

The part you specifically need is:

<!doctype html>
^

SyntaxError: Unexpected token < in JSON at position 0

You're getting an HTML string somewhere instead of a JSON string.

Check your code for where you are using JSON.parse and surround it in a try-catch to find which place the error is occurring.

Collapse
hafizsaifullah profile image
Hafiz Saifullah Author

Than for your kind response.
JSON.parse() is used in crypto/index.js file in following method...,

const syncWithRootState = ()=> {
    request({ url: `${ROOT_NODE_ADDRESS}/api/bocks` }, (error, response, body)=> {
        if (!error && response.statusCode === 200) {
            const rootChain = JSON.parse(body);

            console.log('replace transaction pool map on a sync with', rootChain);
            blockchain.replaceChain(rootChain);
        }
    });

    request({ url: `${ROOT_NODE_ADDRESS}/api/transaction-pool-map` }, (error, response, body) => {
        if (!error && response.statusCode === 200) {
            const rootTransactionPoolMap = JSON.parse(body);

            console.log('replace transaction pool map on a sync with', rootTransactionPoolMap);
            transactionPool.setMap(rootTransactionPoolMap);
        }
    });
}

what changing should be done???

Collapse
dcodeyt profile image
Dom (dcode)

It's possible that the API you're using supports either an HTML or JSON response. You could try setting the Accept header to "application/json" to see if you then get a JSON response back.

Thread Thread
hafizsaifullah profile image
Hafiz Saifullah Author

Thank You @dom for your kind response, but I am new to coding, so I am facing troubles to understand that what is Accept header and how can I set it to "application/json".

Collapse
garretharp profile image
Garret • Edited on

From the original error message, the log in the first request was made "replace transaction pool map on a sync with {}" which means the second request is the issue.

The API response from /api/transaction-pool-map is giving an HTML document rather than a JSON response. You will need to see what exactly the issue is on the API side of this.

However, also for the fact that you do not want your app to error out like that on users, you should also surround the JSON parse code with try-catch or create a new function that safely parses JSON without crashing.

For example a safe parse might be:

function safeParse (data) {
  try {
    const result = JSON.parse(data);
    return result; // Success valid JSON
  } catch (e) {
    console.error('JSON data error', data, e)
    return undefined; // Data was not valid JSON
  }
}
Thread Thread
hafizsaifullah profile image
Hafiz Saifullah Author

When I run only one instance of app, either by using npm run dev or by using npm run dev-peer, it works fine. but when I try to run a second instance, app is crashed.
Is there may be an issue with installation or use of "cross-env"???

Collapse
hafizsaifullah profile image
Hafiz Saifullah Author

Thanx to @Garret, I have resolved my issue by replacing

const rootChain = JSON.parse(body);
console.log('replace transaction pool map on a sync with', rootChain);
blockchain.replaceChain(rootChain);

with

function safeParse (body) {
                const rootChain = JSON.parse(body);
                console.log('replace transaction pool map on a sync with', rootChain);
                blockchain.replaceChain(rootChain);
}
Collapse
hafizsaifullah profile image
Hafiz Saifullah Author

Another occurrence of JSON.parse() is in crypto/app/pubsub.js file in listener() method.
Following is listener() method.

listener() {
        return {
            message: messageObject => {
                const { channel, message } = messageObject;

                console.log(`Message received. Channel: ${channel}. Message: ${message}`);
                const parsedMessage = JSON.parse(message);

                switch(channel) {
                    case CHANNELS.BLOCKCHAIN:
                        this.blockchain.replaceChain(parsedMessage, true, () => {
                            this.transactionPool.clearBlockchainTransactions({
                                chain: parsedMessage 
                            });
                        });
                        break;
                    case CHANNELS.TRANSACTION:
                        if (!this.transactionPool.existingTransaction({
                            inputAddress: this.wallet.publicKey
                        })) {
                            this.transactionPool.setTransaction(parsedMessage);
                        }
                        break;
                    default:
                        return;
                }
            }
        }
    }