- Published on ·
- Time to read
- 3 minute read
Fighting FedEx with DevTools
- Authors
- Name
- Patrick Hulce
- @patrickhulce
It's the age-old story: software engineer tries to use a buggy website, spends way more time than they should debugging it. This was me trying to set my vacation hold for a recent family trip, but little did I know, this was just the beginning of my boxing match with FedEx and the eventual rare victory I was about to claim!
Logging in to FedEx Delivery Manager, I attempted to use the Vacation Hold feature, but was greeted with a blank UI.
"No problem," I thought, "I'll just check the Developer Console." But what did I find there? A classic JavaScript error: "undefined is not a function."
Uncaught TypeError: undefined is not a function
at h (eval at <anonymous> (jquery-1.8.3.min.js:2:14136), <anonymous>:48:158)
at f (eval at <anonymous> (jquery-1.8.3.min.js:2:14136), <anonymous>:50:300)
at eval (eval at <anonymous> (jquery-1.8.3.min.js:2:14136), <anonymous>:9:216)
at c.checkAndLoadScripts (eval at <anonymous> (jquery-1.8.3.min.js:2:14136), <anonymous>:12:94)
at c.init (eval at <anonymous> (jquery-1.8.3.min.js:2:14136), <anonymous>:9:185)
at HTMLDivElement.eval (eval at <anonymous> (jquery-1.8.3.min.js:2:14136), <anonymous>:5:3)
at Function.each (jquery-1.8.3.min.js:2:14440)
at init.each (jquery-1.8.3.min.js:2:11217)
at Object.complete (jquery-1.8.3.min.js:2:79370)
at l (jquery-1.8.3.min.js:2:16996)
at Object.fireWith (jquery-1.8.3.min.js:2:17783)
at T (jquery-1.8.3.min.js:2:81117)
at XMLHttpRequest.r (jquery-1.8.3.min.js:2:86563)
at Object.g [as apply] (77371e2372ae5cd0a0e5f981ba0cc5db9001192124f:24:474)
at XMLHttpRequest.<anonymous> (adrum-4.5.17.2890.js:29:163)
at Object.g [as apply] (77371e2372ae5cd0a0e5f981ba0cc5db9001192124f:24:474)
Feeling nerd sniped now, I clicked on the stack trace, hoping for some answers. But what did I get instead? A generic rethrow of the error, completely unhelpful. So, I did what any self-respecting, deeply stereotyped software engineer would do. I enabled "Pause on Caught Exceptions", grabbed a Mountain Dew, and refreshed that sucker.
Huzzah! Finally, the real source of the error was revealed: a missing jQuery plugin named "dateinput."
Being the resourceful, desperate-for-excitement engineer-on-paternity-leave that I am, I explored the jQuery object a bit and noticed a similarly named datepicker
plugin was available. I decided to monkeypatch dateinput
with it and give it another try.
$.prototype.dateinput = $.prototype.datepicker
And, to my joy, it worked! Sort of. The UI loaded, but I was still getting errors when trying to save the vacation hold.
Undeterred, I popped open the network panel to see what was up. I found the culprit: Date validation errors! Sure enough the datepicker was setting the year incorrectly despite displaying 2023 in the UI.
Feeling the light at the end of the tunnel now, I quickly copied the network request as a curl
command, modified the date to match my desired format, ran in in my shell, and...
curl 'https://api.fedex.com/deliverymanager/v3/addresses/ID_GOES_HERE/vacationholds' \
-H 'authority: api.fedex.com' \
-H 'authorization: Bearer TOKEN_GOES_HERE' \
-H 'content-type: application/json' \
-H 'origin: https://www.fedex.com' \
-H 'referer: https://www.fedex.com/apps/myprofile/deliverymanager/?locale=en_US&cntry_code=us&wpro=true' \
--data-raw '{"saveVacationHoldControlParameters":{"actionType":"ADD"},"vacationHolds":[{"vacationHoldDetail":{"beginDate":"Jan-24-2023","endDate":"Jan-31-2023"}}]}' \
--compressed
Eureka! It worked!
So, the moral of the story is: when dealing with buggy websites, JavaScript errors, and frustration with the failures of a multi-billion dollar corporation in your hometown, never give up! With a bit of determination, a healthy dose of jQuery monkeypatching, and some spare paternity leave on your hands, anything is possible.