been a while since I never code any bugs anymore but I thought I'd mention:
if you have rails webpacker upgrade issues with the webpack loader not finding random files when you build in staging, try moving pipeline and compilation and babel related dependencies out of devDependencies in your package.json and into the main dependencies block. worked for me!
facepalms: 7 (only took 5 hours to figure it out...)
Tuesday, March 17, 2020
Saturday, July 13, 2019
compiling and then transpiling sveltejs: babeljs, webpack, and a safari 9 problem
Been 2 years since my last post here!
just had a very fun deep dive into this annoying bug that was only affecting this one old browser.
I wrote it up here:
https://stackoverflow.com/questions/57019417/how-to-transpile-compiled-svelte-with-babel-for-safari-9/57019418#57019418
Anyway if you haven't checked out https://svelte.dev I highly encourage it - it's faster, easier, and cooler than reactjs.
This bug took me 5 hours to find and fix, but it was a fun and interesting sleuthing session the entire time that has left me feeling proud of my abilities, so I'm gonna go with facepalms: only 2 on this one.
just had a very fun deep dive into this annoying bug that was only affecting this one old browser.
I wrote it up here:
https://stackoverflow.com/questions/57019417/how-to-transpile-compiled-svelte-with-babel-for-safari-9/57019418#57019418
Anyway if you haven't checked out https://svelte.dev I highly encourage it - it's faster, easier, and cooler than reactjs.
This bug took me 5 hours to find and fix, but it was a fun and interesting sleuthing session the entire time that has left me feeling proud of my abilities, so I'm gonna go with facepalms: only 2 on this one.
Tuesday, April 25, 2017
mobile touch gotcha
I once made an angular firebase demo site called Fridge Magnets With Friends.
You can move magnets around on a virtual fridge. This involves a lot of dragging elements.
One day mobile drag stopped working, even tho I employed the clever jquery ui touch punch.
I spent hours switching the whole thing to use ngDraggable, because their mobile demo did work in mobile. Altho using ngDraggable required me to take out jquery (actually it didn't, but some forums said that would help make it work in mobile) - so I spent a while redoing the angular app without jquery.
Moment of truth: no luck.
Finally I hijacked the browser with a little shim code:
Because for the life of me I couldn't figure out why my elements weren't receiving the touchstart event in mobile.
This way I could see what element the e event was pointing to.
Turns out my footer CSS was very improperly done and covering the entire screen, so the event for touchstart, which has to have a stoppropogate() for other reasons in mobile only, never made it to the dragable elements.
Took out the footer and both solutions started working; however, jquery-ui + touch-punch still worked better than ngDraggable, so in the end, 4 hours of work (work that was, admittedly, kind of fun) got reduced to commenting out a couple lines of html. At least I understand mobile touch events now.
facepalms: 9.5
You can move magnets around on a virtual fridge. This involves a lot of dragging elements.
One day mobile drag stopped working, even tho I employed the clever jquery ui touch punch.
I spent hours switching the whole thing to use ngDraggable, because their mobile demo did work in mobile. Altho using ngDraggable required me to take out jquery (actually it didn't, but some forums said that would help make it work in mobile) - so I spent a while redoing the angular app without jquery.
Moment of truth: no luck.
Finally I hijacked the browser with a little shim code:
});$document.on('touchstart', function(e){console.log(e)
Because for the life of me I couldn't figure out why my elements weren't receiving the touchstart event in mobile.
This way I could see what element the e event was pointing to.
Turns out my footer CSS was very improperly done and covering the entire screen, so the event for touchstart, which has to have a stoppropogate() for other reasons in mobile only, never made it to the dragable elements.
Took out the footer and both solutions started working; however, jquery-ui + touch-punch still worked better than ngDraggable, so in the end, 4 hours of work (work that was, admittedly, kind of fun) got reduced to commenting out a couple lines of html. At least I understand mobile touch events now.
facepalms: 9.5
Wednesday, April 19, 2017
CSS property of the day: pointer-events
Do you have an absolutely positioned div that you want to show up on top of another element, but you want click and hover events (for instance) to pass through to the back element? Not such an uncommon use case!
just call our old (new, for me) friend
facepalms: 1 (either I'm getting better at CSS or I just got lucky. According to this hilarious article, I got lucky.)
just call our old (new, for me) friend
pointer-events: none;And it'll pass those events right through.
facepalms: 1 (either I'm getting better at CSS or I just got lucky. According to this hilarious article, I got lucky.)
Saturday, March 11, 2017
quick note on webpack imports and es6 class inheritance
I know it's crazy that I'm only now using modern javascript class inheritance for the first time, but I've been more of a backend programmer most of my career.
I've got a new hobby project that I'm doing with modern webpack / es6 / vue.js, and I just learned something that I didn't find an obvious answer to in the googs.
Basically, I'd been creating utility files with instantiated objects saved as var whatever or let whatever and then exported at the bottom:
export default {
obj: obj
}
And this was all well and good. But then when I wanted to define a class in the same file, the export default was overriding keyword "this". So the functions defined on the class referencing this were actually referencing my export default. I could use a fairly circular reference to get back to the instantiated class object, but really that whole route is silly.
The way to make this work is to define (but not instantiate) each class in its own file. The class itself is your export default in that file:
export default YourClass extends Whatever {
constructor () {
this.stuff
}
yourFunction () {
this.stuff + 1
}
}
Then instantiate the class and use it in another file. Should have been obvious but well es6 takes some getting used to.
Wednesday, December 2, 2015
on being a professional coder
I recently finished Robert "Uncle Bob" Martin's The Clean Coder and I'd like to use this space to share, very briefly, my takeaways from the book, as I head into a new team lead position.
- Accurate estimation of coding tasks is essential if you want to maintain trust between coders and managers
- don't be afraid to push estimation back due to scope creep, etc
- TDD is a way to write better code faster in the long run
- (I already knew this but it was good to hear it again [and again, and again, and again])
- Pair programming is also a way to write better code faster in the long run
- Never tried this in depth, but I'd really like to. Guess as a team lead that might even be up to me!
anyway I'm inspired to be more professional in my coding life, so I guess he succeeded. Book's a quick read, too.
Sunday, September 20, 2015
ad blocking "controversy" aka foolishness
tl;dr: If your website can't make money without crappy ads, and nobody looks at your crappy ads because of advances in technology, then blaming that technology puts you squarely on the wrong side of history.
The creator of peace, one of the most popular iOS ad blocking apps, just pulled his app after a day and a half because it "didn't feel right" to him. While that's his choice, this strikes me as misguided.
There's been a lot of media coverage lately about ad blocking, and complaints about a regurgitated and irrelevant tech news cycle aside, I have seen a quite a few well meaning people stating something like:
We would only improve the internet by striking back against giant, centralized ad serving systems. How anyone could honestly defend cross-site targeted ads is beyond me. Do they improve anyone's browsing experience? Do they honestly make all that much money for the sites that run them? For the businesses that pay for them?
I humbly submit that any website that subsists on google (or similar, but right now it's mostly google)'s ad network, that could not possibly conceive of another way to monetize (of which I'll speak more below) does not deserve to make money. This is the good part of capitalism. This is how we improve technology and social organization as a species. This is the process that government interruption / manipulation frequently subverts (see: the DMCA, drug laws, FCC regulation, oil subsidies, etc).
In fact, the DMCA is a useful parallel from recent history: Pirating music is very different from stealing a physical CD, all whiny record execs to the side. But a powerful industry complained that their business model had become obsolete, and instead of letting that business model die a natural death, our government guaranteed it with the DMCA's intellectual property laws. As a result, we are stuck with all sorts of negative externalities. I'd write more about it but Cory Doctorow explains it way better.
Without the DMCA, all the useless blood sucking middlemen (aka giant record labels) would have evolved or shrunken away, and maybe our entire culture would have been better off (fewer cookie cutter pop stars, anyone?). Smaller labels would have had no trouble monetizing, just like they do today anyway - with more interesting physical releases, more/better concerts, a resurgence in vintage-format media, pay-what-you-can downloads, free streaming to help spread music, and much more.
Ad blocking is the same way. I wouldn't be surprised if Google lobbied congress to pass an anti-adblocking law. When you think about it, and for the reasons stated here, it'd be very similar to the DMCA. Google has enough at stake here to make spending hundreds of millions in lobbying dollars quite worthwhile for Google. And as we know, congress is cheap.
Instead of rooting for the old ad-supported paradigm, let's brainstorm how a newer, sleeker web could monetize:
The creator of peace, one of the most popular iOS ad blocking apps, just pulled his app after a day and a half because it "didn't feel right" to him. While that's his choice, this strikes me as misguided.
There's been a lot of media coverage lately about ad blocking, and complaints about a regurgitated and irrelevant tech news cycle aside, I have seen a quite a few well meaning people stating something like:
ads make the internet go round. it's irresponsible to enable ad blocking software.As a web developer and armchair philosopher, I'm on the record as being for ad blocking software, insofar as I think it only makes the internet a better place. Crucially, I'd remind the reader that under our current more-or-less capitalist system, no business models are guaranteed by government or (mostly) morality. And tho I think capitalism has some blind spots (see healthcare, maybe?), advertising on the internet ain't one of them.
We would only improve the internet by striking back against giant, centralized ad serving systems. How anyone could honestly defend cross-site targeted ads is beyond me. Do they improve anyone's browsing experience? Do they honestly make all that much money for the sites that run them? For the businesses that pay for them?
I humbly submit that any website that subsists on google (or similar, but right now it's mostly google)'s ad network, that could not possibly conceive of another way to monetize (of which I'll speak more below) does not deserve to make money. This is the good part of capitalism. This is how we improve technology and social organization as a species. This is the process that government interruption / manipulation frequently subverts (see: the DMCA, drug laws, FCC regulation, oil subsidies, etc).
In fact, the DMCA is a useful parallel from recent history: Pirating music is very different from stealing a physical CD, all whiny record execs to the side. But a powerful industry complained that their business model had become obsolete, and instead of letting that business model die a natural death, our government guaranteed it with the DMCA's intellectual property laws. As a result, we are stuck with all sorts of negative externalities. I'd write more about it but Cory Doctorow explains it way better.
Without the DMCA, all the useless blood sucking middlemen (aka giant record labels) would have evolved or shrunken away, and maybe our entire culture would have been better off (fewer cookie cutter pop stars, anyone?). Smaller labels would have had no trouble monetizing, just like they do today anyway - with more interesting physical releases, more/better concerts, a resurgence in vintage-format media, pay-what-you-can downloads, free streaming to help spread music, and much more.
Ad blocking is the same way. I wouldn't be surprised if Google lobbied congress to pass an anti-adblocking law. When you think about it, and for the reasons stated here, it'd be very similar to the DMCA. Google has enough at stake here to make spending hundreds of millions in lobbying dollars quite worthwhile for Google. And as we know, congress is cheap.
Instead of rooting for the old ad-supported paradigm, let's brainstorm how a newer, sleeker web could monetize:
- more thoughtfully crafted ads, negotiated more directly with businesses, not served from ad farms, and hence not so easily blocked (aka native ads)
- opt-in / crowdfunded memberships with perks (plenty of tipping services out there on the net)
- merchandising
- online or offline "rent party" type fundraisers, where website fans could meet and mingle
- In general, new products that people are more interested in paying for
To reiterate and conclude: if your website can't make money without crappy ads, and nobody looks at your crappy ads because of advances in technology, then blaming that technology puts you squarely on the wrong side of history.
A similar opinion I just found:
https://snelling.io/on-ad-blocking
A similar opinion I just found:
https://snelling.io/on-ad-blocking
Labels:
ad blocking,
cory doctorow,
deep thoughts,
dmca,
google,
laws
Monday, February 23, 2015
talk about facepalms
learning javascript: valuable
relearning trigonometry: way valuable
spending 2 hours trying to code Math.atan2 in plain javascript because you were too stubborn to spend 6 seconds searching for how to get that stupid angle at any quadrant of the unit circle: priceless!
in related news, Math.atan2 is very useful (altho why its arguments are (deltaY, deltaX) and not vice versa eludes me), and pixi.js is very fun.
relearning trigonometry: way valuable
spending 2 hours trying to code Math.atan2 in plain javascript because you were too stubborn to spend 6 seconds searching for how to get that stupid angle at any quadrant of the unit circle: priceless!
in related news, Math.atan2 is very useful (altho why its arguments are (deltaY, deltaX) and not vice versa eludes me), and pixi.js is very fun.
Wednesday, February 18, 2015
unexplainable 500 errors with flask and jquery ajax on google app engine
I was trying to do something simple - get a preloaded partial from the server via ajax. my api call worked directly in the browser, worked when I ran it with $.get() from the console after the page was loaded, but was returning 500 during page load (as in, only failing when it was called as js running at after dom load). I could confirm that the correct flask view was running and succeeding using logging, but the 500 I was getting had NO responsetext, and nothing useful..
After fighting and fruitless searching for 40 minutes, I disabled the flask debug toolbar. Voila! everything worked as expected.
Moral of the story: F$@# the flask debug toolbar.
facepalms: 8
After fighting and fruitless searching for 40 minutes, I disabled the flask debug toolbar. Voila! everything worked as expected.
Moral of the story: F$@# the flask debug toolbar.
facepalms: 8
Labels:
ajax,
app engine,
facepalm,
flask,
flask debug toolbar,
jquery
Tuesday, February 3, 2015
displayport / hdmi not recognized in ubuntu 14 when eighth inch audio jack is not plugged into sound system (lenovo t430s)
yeah you read that title right. can you believe it? I fought with my computer for an hour early this morning, installed a super fresh kernel, played with intel drivers, but nothing wanted to make ubuntu 14 recognize the displayport. It was working the night before!
finally gave up and went to put some music on. boom! screen turned on. what the hell? unplugged the eighth inch cable again. boom! screen turned off. also, the amplifier turned off and on each time I plugged or unplugged the cable. I'm still 99% baffled here but there's another clue - a buzz on the line that I can audibly hear thru the speakers when this particular sound system is connected, that also changes when I restart the computer.
Note that when I plugged headphones into the eighth inch jack, the screen did not turn on (altho there may have been some signs of life briefly).
So best guess (which is probably very wrong?) is that there's a loose connection somewhere in the laptop, and that the added power from my stereo thru the eighth inch connection (which should be flowing the other direction, but this is an input / output jack) is bridging the loose wire? hence the buzz?
UPDATE 6:30pm same night:
scratch the above theory - new shit has come to light!
when I moved my laptop to the living room and plugged the mini displayport into the projector, everything worked as always - without a sound system being plugged in. So then, being the good scientist that I am, I lugged one of my screens into the living room and plugged it into the displayport, and holy moly, it worked fine, no audio cord plugged in. So it's actually proximity to my crazy stereo system that's causing this issue. Unfortunately I don't know enough about sound systems and electronics to posit a complete theory, altho I bet this is enough for someone to be able to. My general idea now is that the magnetic field cast by the bass amplifier on the floor right next to the monitor is somehow involved.
As before, if you have any ideas, I'd love to hear em.
facepalms: 7.5 (would have been 10 but tempered by the sweet relief of seeing that screen turn on)
finally gave up and went to put some music on. boom! screen turned on. what the hell? unplugged the eighth inch cable again. boom! screen turned off. also, the amplifier turned off and on each time I plugged or unplugged the cable. I'm still 99% baffled here but there's another clue - a buzz on the line that I can audibly hear thru the speakers when this particular sound system is connected, that also changes when I restart the computer.
Note that when I plugged headphones into the eighth inch jack, the screen did not turn on (altho there may have been some signs of life briefly).
So best guess (which is probably very wrong?) is that there's a loose connection somewhere in the laptop, and that the added power from my stereo thru the eighth inch connection (which should be flowing the other direction, but this is an input / output jack) is bridging the loose wire? hence the buzz?
UPDATE 6:30pm same night:
scratch the above theory - new shit has come to light!
when I moved my laptop to the living room and plugged the mini displayport into the projector, everything worked as always - without a sound system being plugged in. So then, being the good scientist that I am, I lugged one of my screens into the living room and plugged it into the displayport, and holy moly, it worked fine, no audio cord plugged in. So it's actually proximity to my crazy stereo system that's causing this issue. Unfortunately I don't know enough about sound systems and electronics to posit a complete theory, altho I bet this is enough for someone to be able to. My general idea now is that the magnetic field cast by the bass amplifier on the floor right next to the monitor is somehow involved.
As before, if you have any ideas, I'd love to hear em.
facepalms: 7.5 (would have been 10 but tempered by the sweet relief of seeing that screen turn on)
Tuesday, March 18, 2014
how to tell if an API works well before you write the integration
I connect with APIs for a living, or at least for part of a living. I do it all the time.
Often the ops team will ask me - how long to do an integration with ESP X, or Analytics firm Y? short of actually doing the integration, it used to be hard to give a good answer to this question. Now, tho, I have the perfect heuristic - it's never failed me.
Just take a look at the API docs. doesn't really matter what they say; if they're well formatted, easy to navigate, and well thought through, API integration will be a breeze. That simple.
Something like this makes an easy heuristic:
Often the ops team will ask me - how long to do an integration with ESP X, or Analytics firm Y? short of actually doing the integration, it used to be hard to give a good answer to this question. Now, tho, I have the perfect heuristic - it's never failed me.
Just take a look at the API docs. doesn't really matter what they say; if they're well formatted, easy to navigate, and well thought through, API integration will be a breeze. That simple.
Something like this makes an easy heuristic:
- no API docs - refuse to do the job
- API docs not available online but emailed to you in pdf form (or shared as gdoc): 40-50 hours
- API docs in one monolithic html page: 30-40 hours (obviously all of this depends on depth of integration too)
- docs have a formatted nav bar at left and some readable styling: 20-30 hours
- docs have the above in addition to "web 3.0" style formatting, and maybe some helpful examples: 10-20 hours
- docs have the above plus toggleable examples in different programming languages, maybe a link to wrapper libraries, are well written, and code blocks are formatted with special code block formatting: 1-10 hours.
you can use this, free of charge :)
best part of it is that I taught the ops team how to do this, and now they know exactly what estimate I'll give before they even ask me. Pretty soon they won't even need me at all, what with services like zapier.
Tuesday, February 4, 2014
for the record
the python CSV package is not as useful as it could be. no unicode support, can't handle all sorts of useful things like switching out the line delimiter (unless I'm missing something), and frequently just falls over for no reason.
I always try to use it, because modularity, and DRY, and yet I end up just writing up a quick csv parser myself for the job at hand like 60% of the time. Makes me think I should look for other CSV parsing packages, or just write my own.
I always try to use it, because modularity, and DRY, and yet I end up just writing up a quick csv parser myself for the job at hand like 60% of the time. Makes me think I should look for other CSV parsing packages, or just write my own.
Wednesday, October 30, 2013
more python SUDS advice
Everybody knows the a SOAP API is a horrid thing to work with, even a well designed one. But everybody also knows that SOAP is going to be around for a while.
Recently, while working with the ExactTarget SOAP API in Python, I figured out another helpful trick with SUDS, which is the main python SOAP wrapper.
Let me preface this by saying that suds is not a great library; particularly, it was written by and for people from another era of web development and does not stand up to today's needs. Why doesn't somebody write a better one? because everyone who does modern web dev hates SOAP in the first place.
But anyway, one annoying feature of suds is that when you create an object from its object factory, it always fills in all properties with an empty string, even those that are optional and have sane defaults. So essentially, it breaks all objects right out of the gate, forcing you to go through one by one and choose those sane defaults explicitly.
However, there's another way - for any properties that are giving you trouble in this fashion, just delete them after creating the object:
del object.AnnoyingProperty
Suds will then not send the property, allowing the API server to choose the sane default.
facepalms: 6
Recently, while working with the ExactTarget SOAP API in Python, I figured out another helpful trick with SUDS, which is the main python SOAP wrapper.
Let me preface this by saying that suds is not a great library; particularly, it was written by and for people from another era of web development and does not stand up to today's needs. Why doesn't somebody write a better one? because everyone who does modern web dev hates SOAP in the first place.
But anyway, one annoying feature of suds is that when you create an object from its object factory, it always fills in all properties with an empty string, even those that are optional and have sane defaults. So essentially, it breaks all objects right out of the gate, forcing you to go through one by one and choose those sane defaults explicitly.
However, there's another way - for any properties that are giving you trouble in this fashion, just delete them after creating the object:
del object.AnnoyingProperty
Suds will then not send the property, allowing the API server to choose the sane default.
facepalms: 6
Friday, October 18, 2013
How to do get a good security audit for your startup
Recently at SimpleRelevance we decided it was time for a security audit on our website and especially our dashboard. We have quite a bit of client information that we would never want to share with the world.
Security audits are kind of like STD testing - even when you feel 100% fine, it's better safe than sorry.
Unfortunately, also like STD testing, if you cheap out, you won't get tested for everything.
So our problem was - how do we not get ripped off, while still ensuring a comprehensive audit - we're talking more than just simple pentests here. It's so hard to verify that you've gotten a good security audit, since the company can just come back and say "we didn't find any issues - your system is bulletproof!", and you can't prove that negative. In the end we did a lot of research and interviews and chose based on the data at hand. But since then I've thought of a fun way that might work even better.
1) through research, find N>1 companies that you'd consider paying for research.
2) bargain each one down (you were going to do this anyway, right? We ended up paying about 65% of the original ask for the company we chose).
3) tell each one: "I'll make you a deal. I'll pay you full price on the test, if you agree to the stipulation that I'm making this same deal with another security company, and whoever finds fewer or less important security holes doesn't earn any money, and whoever finds the most gets the full price [plus 10% if you need to sweeten it]".
4) Some of the companies are going to say no. Decide which company is most excited by the idea of the deal - they are clearly the winner, so congrats - you found the best one! Tell them none of the others would take the deal, so unfortunately you can't do it, but you'll still pay them the discounted rate you'd already agreed upon for a full audit, and you applaud their style.
Security audits are kind of like STD testing - even when you feel 100% fine, it's better safe than sorry.
Unfortunately, also like STD testing, if you cheap out, you won't get tested for everything.
So our problem was - how do we not get ripped off, while still ensuring a comprehensive audit - we're talking more than just simple pentests here. It's so hard to verify that you've gotten a good security audit, since the company can just come back and say "we didn't find any issues - your system is bulletproof!", and you can't prove that negative. In the end we did a lot of research and interviews and chose based on the data at hand. But since then I've thought of a fun way that might work even better.
1) through research, find N>1 companies that you'd consider paying for research.
2) bargain each one down (you were going to do this anyway, right? We ended up paying about 65% of the original ask for the company we chose).
3) tell each one: "I'll make you a deal. I'll pay you full price on the test, if you agree to the stipulation that I'm making this same deal with another security company, and whoever finds fewer or less important security holes doesn't earn any money, and whoever finds the most gets the full price [plus 10% if you need to sweeten it]".
4) Some of the companies are going to say no. Decide which company is most excited by the idea of the deal - they are clearly the winner, so congrats - you found the best one! Tell them none of the others would take the deal, so unfortunately you can't do it, but you'll still pay them the discounted rate you'd already agreed upon for a full audit, and you applaud their style.
Tuesday, June 11, 2013
ipython and the django shell: strange scoping errors
this is a minor issue that has annoying repercussions. on most versions of django, if you use ipython and start it with ./manage.py shell, you cannot define global variables and then use them in local functions. it gets ugly quick. more info here:
https://github.com/ipython/ipython/issues/62
patch is here:
https://github.com/django/django/pull/512/files
and it definitely fixes the issue.
https://github.com/ipython/ipython/issues/62
patch is here:
https://github.com/django/django/pull/512/files
and it definitely fixes the issue.
Tuesday, January 15, 2013
python httplib2 7.x and ssl
this is not a completely new issue, and the internet helped me find the solution in about 5 minutes, but it was not very clear or obvious so I thought I'd write it down succinctly for posterity:
Python's httplib2 package did not validate ssl certificates in versions < 7.0, and started to from 7.0 and up. Unfortunately, it ships with its own set of trusted ssl certificates which comprise only a medium-sized subset of all of your favorite sites' certs (for instance, wikipedia fails when pinged at https://en.wikipedia.org!). The error looks like this:
So the solution is to use ubuntu's system default cert file, which lives at /etc/ssl/certs/ca-certificates.crt. I ended up overwriting the one that shipped with httplib2, which fixes the problem globally, but fails if we ever reinstall httplib2. Hence this blog post for posterity. If anyone knows of another way to globally install a new certificates file for httplib2 without changing the package itself, I'm all ears. I might just onboard the package to our project (but then I have to remember never to pip install it...).
by the way, this page was most helpful.
facepalms: 3
Python's httplib2 package did not validate ssl certificates in versions < 7.0, and started to from 7.0 and up. Unfortunately, it ships with its own set of trusted ssl certificates which comprise only a medium-sized subset of all of your favorite sites' certs (for instance, wikipedia fails when pinged at https://en.wikipedia.org!). The error looks like this:
File "/home/deploy/.virtualenvs/sandbox.koaladeal.com/local/lib/ python2.7/site-packages/ httplib2/__init__.py", line 1597, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/home/deploy/.virtualenvs/sandbox.koaladeal.com/local/lib/ python2.7/site-packages/ httplib2/__init__.py", line 1345, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/home/deploy/.virtualenvs/sandbox.koaladeal.com/local/lib/ python2.7/site-packages/ httplib2/__init__.py", line 1281, in _conn_request
conn.connect()
File "/home/deploy/.virtualenvs/sandbox.koaladeal.com/local/lib/ python2.7/site-packages/ httplib2/__init__.py", line 1036, in connect
raise SSLHandshakeError(e)
SSLHandshakeError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
So the solution is to use ubuntu's system default cert file, which lives at /etc/ssl/certs/ca-certificates.crt. I ended up overwriting the one that shipped with httplib2, which fixes the problem globally, but fails if we ever reinstall httplib2. Hence this blog post for posterity. If anyone knows of another way to globally install a new certificates file for httplib2 without changing the package itself, I'm all ears. I might just onboard the package to our project (but then I have to remember never to pip install it...).
by the way, this page was most helpful.
facepalms: 3
Tuesday, November 20, 2012
how to not run your business
tell me - if you're going to pay for hosting for a corporate wordpress blog, what's the chance you're not going to use your corporate email account and what's the chance you're not going to host the blog at your corporate url? in other words, for what business would this error message not come up?
None. Facepalms: 5 (horrifically hilarious, luckily not a problem I have to deal with today.)
Wednesday, October 10, 2012
magento and the dreaded WebFault: Product not exists
Sometimes using SOAP with the Magento V2 API you may search for a product's image (by calling catalog_product_attribute_media.list with the sku as only argument) and receive this hilarious message:
"Product not exists." <-- you can't make this stuff up!
Hilarious but sad, because there's the image right there, laughing at you from the website, and yet your API doesn't have access.
luckily there's an easy fix. in short: append a space to the end of the sku. done. psha. magento, we love to hate you.
facepalms: 5
"Product not exists." <-- you can't make this stuff up!
Hilarious but sad, because there's the image right there, laughing at you from the website, and yet your API doesn't have access.
luckily there's an easy fix. in short: append a space to the end of the sku. done. psha. magento, we love to hate you.
facepalms: 5
Monday, October 8, 2012
celery + djcelery problem with virtualenv and virtualenvwrapper
this is a tricky one - out of nowhere, production env boxes started failing at celery startup with:
ImportError: cannot import name current_app
when importing djcelery. Versions of celery were fine.
It turns out if you import celery and run
import celery.current_app you'll see the real problem, which is that the virtualenv binary is out of sync with the new python binary from a recent security update - specifically, os.urandom has been changed/removed.
if you have virtualenvwrapper, and you let $ENV=YOUR_ENVIRONEMNT_NAME
So the answer is:
deactivate (in case an env is running)
cd ~/$ENV_HOME (.virtualenvs, for me)
rm $ENV/bin/python
virtualenv $ENV
this will rebuild your python binary with the correct python post-security fix, without losing any other packages. happy hacking!
Sunday, July 8, 2012
redis vs rabbit with django celery
if you're planning on putting a django celery app into heavy production use, your message queue matters. At SimpleRelevance we used RabbitMQ for months, since it's probably the most famous of the available options.
It took about 8 seconds to restart out celery workers, but that was fine. In general it was fairly reliable, and the way it routed tasks to different celery workers on different boxes often felt like magic.
However, getting results of a task back using rabbit as a result backend was a different story - it often took minutes, even hanging the box it was on. And these weren't big results either.
So for the record here, we switched to Redis. Not only is restarting about 3X faster, but as a results backend it also wins - no more hanging, and results come back as soon as they're ready. My sysops also tells me it was much easier to install and configure.
boom.
----
update!
actually it turns out redis starts to perform very badly when faced with a deep queue in our production environment. So the optimal setup for us turns out to be RabbitMQ for the queue handling, and Redis for the result backend.
It took about 8 seconds to restart out celery workers, but that was fine. In general it was fairly reliable, and the way it routed tasks to different celery workers on different boxes often felt like magic.
However, getting results of a task back using rabbit as a result backend was a different story - it often took minutes, even hanging the box it was on. And these weren't big results either.
So for the record here, we switched to Redis. Not only is restarting about 3X faster, but as a results backend it also wins - no more hanging, and results come back as soon as they're ready. My sysops also tells me it was much easier to install and configure.
boom.
----
update!
actually it turns out redis starts to perform very badly when faced with a deep queue in our production environment. So the optimal setup for us turns out to be RabbitMQ for the queue handling, and Redis for the result backend.
Subscribe to:
Posts (Atom)