Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: [ERR_STREAM_DESTROYED] Cannot call write after a stream was destroyed. #91

Open
KylianJay opened this issue Apr 12, 2024 · 1 comment

Comments

@KylianJay
Copy link

`Hi! I'm getting an error that seemingly came out of nowhere, as it didn't happen during my testing phase, but did happen during my production phase.

When trying to print a receipt using my below code:
`app.post('/create/order', async (req, res) => {
// we're getting an order! let's print it!
console.log("printing order with id: #" + req.body.orderId)
console.log(req.body)
let foodString = "";
let drinksString = "";
let dessertsString = "";

if (req.body.items && Array.isArray(req.body.items) && req.body.items.length > 0) {
    const donItems = req.body.items[0].don;
    const drinkItems = req.body.items[0].drinks;
    const dessertsItems = req.body.items[0].desserts;

    if (donItems && Array.isArray(donItems)) {
        const food = donItems.map(donItem => {
            let itemString = donItem.name.replace(/[^\P{L}a-zA-Z]/g, '') + ` `;

            // Check if extraToppings exist and is an array before adding the line
            if (Array.isArray(donItem.selectedToppings) && donItem.selectedToppings.length > 0) {
                const options = donItem.selectedToppings.map(topping => topping.name.replace(/[^\P{L}a-zA-Z\s]/g, ''));
                itemString += `\n Options: (${options.join(', ')})`;
            }

            return itemString;
        });
        foodString = food.join("\n ");
    }

    if (drinkItems && Array.isArray(drinkItems)) {
        const drinks = drinkItems.map(drinkItem => {
            let itemString = drinkItem.name.replace(/[^\P{L}a-zA-Z]/g, '') + ``;

            // Check if milkOptions exist before adding the line
            // Check if extraToppings exist and is an array before adding the line
            if (Array.isArray(drinkItem.selectedToppings) && drinkItem.selectedToppings.length > 0) {
                const options = drinkItem.selectedToppings.map(topping => topping.name.replace(/[^\P{L}a-zA-Z\s]/g, ''));
                itemString += `\n Options: (${options.join(', ')})`;
            }

            return itemString;
        });
        drinksString = drinks.join("\n ");
    }

    if (dessertsItems && Array.isArray(dessertsItems)) {
        const desserts = dessertsItems.map(dessertItem => {
            let itemString = dessertItem.name.replace(/[^\P{L}a-zA-Z]/g, '') + ``;

            // Check if extraToppings exist and is an array before adding the line
            if (Array.isArray(dessertItem.selectedToppings) && dessertItem.selectedToppings.length > 0) {
                const options = dessertItem.selectedToppings.map(topping => topping.name.replace(/[^\P{L}a-zA-Z\s]/g, ''));
                itemString += `\n Options: (${options.join(', ')})`;
            }

            return itemString;
        });
        dessertsString = desserts.join("\n ");
    }

    const separationLine = "-------------------------";

    // Check if there are items for Food before adding the separation line
    if (foodString && (drinksString || dessertsString)) {
        foodString += `\n${separationLine}\n`;
    }

    // Check if there are items for Drinks before adding the separation line
    if (drinksString && dessertsString) {
        drinksString += `\n${separationLine}\n`;
    }
}

try {
    const separationLine = "-------------------------";
    console.log("sending " 
    + "Order ID: " + req.body.id
    + "Table: " + req.body.table
    + "Food: " + foodString
    + "Drinks: " + drinksString
    + "Desserts: " + dessertsString
    + "Total: " + req.body.priceTotal
    + "Date: " + req.body.datetime
    + "Notes: " + req.body.notes
    + "to printer")
     device.open(async function(error){
        await printer
        .font('b')
        .align('ct')
        .size(1,1)
        .text("Receipt 1 of 2")
        .style('bu')
        .size(2, 2)
        .text('New order for Table: ' + req.body.table)
        .text(`\n${separationLine}\n`)
        .text('Food: ' + foodString)
        .text('Drinks: ' + drinksString)
        .text('Desserts: ' + dessertsString)
        .text(`\n${separationLine}\n`)
        .text('Notes: ' + req.body.notes)
        .font('a')
        .size(1, 1)
        .text(`\n${separationLine}\n`)
        .text('Total: ' +  req.body.priceTotal)
        .text('Date: ' + req.body.datetime)
        .text('Order ID: ' + req.body.id)
        .text(" ")
        .cut()
        .font('b')
        .align('ct')
        .size(1,1)
        .text("Receipt 2 of 2")
        .style('bu')
        .size(2, 2)
        .text('New order for Table: ' + req.body.table)
        .text(`\n${separationLine}\n`)
        .text('Food: ' + foodString)
        .text('Drinks: ' + drinksString)
        .text('Desserts: ' + dessertsString)
        .text(`\n${separationLine}\n`)
        .text('Notes: ' + req.body.notes)
        .font('a')
        .size(1, 1)
        .text(`\n${separationLine}\n`)
        .text('Total: ' +  req.body.priceTotal)
        .text('Date: ' + req.body.datetime)
        .text('Order ID: ' + req.body.id)
        .text(" ")
        .cut()
        .close()
        if (error) {
            console.log(error)
        }
    })
}
catch (error) {
    console.log(error)
}

res.send("Order: " + req.body.id + " Printed on date: " + req.body.datetime)

})I get the following error:Error [ERR_STREAM_DESTROYED] Cannot call write after a stream was destroyed`
See pictures below for full error:
IMG_5667
IMG_5668

Is there an issue with my code, is it my Node version? (v20.11.0) I can't seem to get it working.

Copy link

dosubot bot commented Apr 12, 2024

The ERR_STREAM_DESTROYED error you're encountering typically indicates an attempt to perform operations on a stream that has already been closed or destroyed. This can happen if your code tries to write to or close a stream that's not in a valid state, often due to asynchronous operations not being managed correctly.

To address this, ensure that your asynchronous operations, especially those involving the printer, are properly sequenced and that you're not attempting to use the printer before it's ready or after it's been closed. Wrapping your printing logic in a Promise and using async/await can help manage these operations more predictively.

Here's a more reliable approach to handle printing asynchronously:

const print = (text) => {
  return new Promise((resolve, reject) => {
    device.open(function (error) {
      if (error) {
        return reject(error);
      }
      printer
        .font('a')
        .align('ct')
        .style('bu')
        .size(1, 1)
        .text(text)
        .cut()
        .close(() => {
          resolve();
        });
    });
  });
};

In this setup, the print function is wrapped in a Promise, ensuring that the device is opened successfully before attempting to print. This method helps in managing the stream's lifecycle more effectively, reducing the likelihood of encountering ERR_STREAM_DESTROYED errors.

Additionally, verify that all libraries, especially escpos and its dependencies, are compatible with your Node.js version (v20.11.0). Incompatibilities between Node.js versions and libraries can lead to unexpected errors, including those related to stream and network issues.

Implementing these suggestions should help mitigate the issues you're experiencing by ensuring proper stream management and asynchronous operation handling. If the problem persists, checking for library compatibility with your Node.js version and ensuring that your asynchronous logic is correctly structured will be crucial steps in troubleshooting further.

Sources

About Dosu

This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant