question

Dan avatar image
Dan asked Jeffrey Blattman commented

Bug in StaticBillPrintJob with invalid order IDs

Hello, I think this is a pretty serious bug which breaks the device printer. I am very open to receiving some kind of bug bounty.


Steps to repro:

  • Create an order in the Register app and leave it Open. Note it's ID.
  • Delete the order in the Orders app.
  • In code, using the order ID you just deleted, call:
  • val deletedOrder = orderConenctor.getOrder(deletedOrderID)
  • val job = StaticBillPrintJob.Builder().order(deletedOrder).build()
  • PrintJobsConnector(context).print(printer, job)

Result:

  • An error is thrown by the Printers app. The print does not complete. The job is given a state of PrintJobsContract.STATE_ERROR. And crucially: all future prints fail until the print queue is cleared in the Printers app. Even rebooting does not fix the issue because a reboot causes the print queue to recreate itself and it tries again.

Desired behavior:

  • Sending a deleted Order to the print job builder doesn't break the printer.
  • Possibly an exception is thrown instead.


Edit:

I have attached relevant logcat which I should have done to begin with. Looks like it specifically falls over when it tries to a print payments which don't exist on the deleted orders I try to print:

W/SeikoMini: onHandleIntent(PrinterIntentService.java:401)[IntentService[PrinterIntentService]]: print failed, printer: Printer{uuid=2RGKEXS4YFB9W, type=SEIKO_MINI_USB, name=Mini, mac=null, ip=null, category=RECEIPT}
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.clover.sdk.v3.order.Order.getPayments()' on a null object reference
        at com.clover.common2.printer.SignatureHelperV3.getPaymentFromOrder(SignatureHelperV3.java:385)

printing_deleted_orders_logcat.txt

OrdersPrint
4 comments
10 |2000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Jeffrey Blattman avatar image Jeffrey Blattman ♦♦ commented ·

Something is wrong in your code. You wrote "order(orderID)" but that method takes an order object, not an ID. There's no way to pass an ID, you have to pass the full Order object.

0 Likes 0 ·
Dan avatar image Dan Jeffrey Blattman ♦♦ commented ·

Thanks Jeff I've updated the question there you are correct I was getting confused and missing a step where I retrieve the order first. It's irrelevant that the order connector correctly throws an exception if you pass in null for the order id so I've removed that.

0 Likes 0 ·
Jeffrey Blattman avatar image Jeffrey Blattman ♦♦ Dan commented ·

Are you getting a non-null order back when you retrieve it? Can you link the logcat also please.

0 Likes 0 ·
Show more comments

1 Answer

·
Jeffrey Blattman avatar image
Jeffrey Blattman answered Jeffrey Blattman commented

The logcat indicates you passed a null order:

W/SeikoMini: onHandleIntent(PrinterIntentService.java:401)[IntentService[PrinterIntentService]]: print failed, printer: Printer{uuid=2RGKEXS4YFB9W, type=SEIKO_MINI_USB, name=Mini, mac=null, ip=null, category=RECEIPT}
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.clover.sdk.v3.order.Order.getPayments()' on a null object reference

When you pass an order object, there should be nothing that depends on that order not being deleted in the backend, or even existing at all. Print jobs are self-contained. They have all the data required to print; they are a snapshot of the data.

4 comments
10 |2000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Dan avatar image Dan commented ·

Alright Jeff you are correct (as always) I think the orders probably were always null I was handing it, unless I was going crazy and there is a slight delay between deleting an order from the Orders app and it removing itself from the order connector or something.


So the issue is just that if you hand it an order of null it will break the printer which is obviously my fault for doing so, but at the same time I think it probably shouldn't break the printer for everyone so it might be worth doing something around that.

0 Likes 0 ·
Jeffrey Blattman avatar image Jeffrey Blattman ♦♦ Dan commented ·
I think it probably shouldn't break the printer for everyone so it might be worth doing something around that.

Yes I get it I had the same thought. Will file an internal issue an think about it.

0 Likes 0 ·
Dan avatar image Dan Jeffrey Blattman ♦♦ commented ·

Hi Jeff I have a new related issue that took me a while to diagnose. Stack trace when I attempt to print is here. Steps are:

  • Create open order with item X
  • Delete item X from Inventory
  • Pay for the order with a custom tender via the api
  • Print the order using
  • StaticBillPrintJob.Builder().order(order).build()

It should throw an error in the Printers app and all subsequent prints on the device fail until the print queue is manually cleared. However I am having trouble reproducing it (tried 5 times there but only 2 orders are broken).

0 Likes 0 ·
Show more comments

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Welcome to the
Clover Developer Community