Tags: bug

37

sparkline

Friday, September 7th, 2018

881410 - Incorrect transforms when stripping subdomains

The latest version of Chrome is removing seams by messing with the display of the URL.

This is a bug.

Wednesday, August 15th, 2018

Google AMP - A 70% drop in our conversion rate. - Rockstar Coders

Google hijacking and hosting your AMP pages (in order to pre-render them) is pretty terrible for user experience and security:

I’m trying to establish my company as a legitimate business that can be trusted by a stranger to build software for them. Having google.com reeks of a phishing scam or fly by night operation that couldn’t afford their own domain.

Tuesday, August 7th, 2018

Console methods

Whenever I create a fetch event inside a service worker, my code roughly follows the same pattern. There’s a then clause which gets executed if the fetch is successful, and a catch clause in case anything goes wrong:

fetch( request)
.then( fetchResponse => {
    // Yay! It worked.
})
.catch( fetchError => {
    // Boo! It failed.
});

In my book—Going Offline—I’m at pains to point out that those arguments being passed into each clause are yours to name. In this example I’ve called them fetchResponse and fetchError but you can call them anything you want.

I always do something with the fetchResponse inside the then clause—either I want to return the response or put it in a cache.

But I rarely do anything with fetchError. Because of that, I’ve sometimes made the mistake of leaving it out completely:

fetch( request)
.then( fetchResponse => {
    // Yay! It worked.
})
.catch( () => {
    // Boo! It failed.
});

Don’t do that. I think there’s some talk of making the error argument optional, but for now, some browsers will get upset if it’s not there.

So always include that argument, whether you call it fetchError or anything else. And seeing as it’s an error, this might be a legitimate case for outputing it to the browser’s console, even in production code.

And yes, you can output to the console from a service worker. Even though a service worker can’t access anything relating to the document object, you can still make use of window.console, known to its friends as console for short.

My muscle memory when it comes to sending something to the console is to use console.log:

fetch( request)
.then( fetchResponse => {
    return fetchResponse;
})
.catch( fetchError => {
    console.log(fetchError);
});

But in this case, the console.error method is more appropriate:

fetch( request)
.then( fetchResponse => {
    return fetchResponse;
})
.catch( fetchError => {
    console.error(fetchError);
});

Now when there’s a connectivity problem, anyone with a console window open will see the error displayed bold and red.

If that seems a bit strident to you, there’s always console.warn which will still make the output stand out, but without being quite so alarmist:

fetch( request)
.then( fetchResponse => {
    return fetchResponse;
})
.catch( fetchError => {
    console.warn(fetchError);
});

That said, in this case, console.error feels like the right choice. After all, it is technically an error.

Coming to a browser near you - faster than ever before!

A great long-term perspective from Rachel on the pace of change in standards getting shipped in browsers:

The pace that things are shipping, and at which bugs are fixed is like nothing we have seen before. I know from sitting around a table with representatives from each browser vendor at the CSS Working Group how important interop is. No-one wants features to be implemented differently in browsers. This is what we were asking for with WaSP, and despite the new complexity of the platform, browsers rendering standard features in different ways is becoming increasingly rare. Bugs happen, sometimes in the browser and sometimes in the spec, but there is a commitment to avoid these and to create a stable platform we can all rely on. It is exciting to be part of it.

Thursday, July 5th, 2018

The trimCache function in Going Offline

Paul Yabsley wrote to let me know about an error in Going Offline. It’s rather embarrassing because it’s code that I’m using in the service worker for adactio.com but for some reason I messed it up in the book.

It’s the trimCache function in Chapter 7: Tidying Up. That’s the reusable piece of code that recursively reduces the number of items in a specified cache (cacheName) to a specified amount (maxItems). On page 95 and 96 I describe the process of creating the function which, in the book, ends up like this:

 function trimCache(cacheName, maxItems) {
   cacheName.open( cache => {
     cache.keys()
     .then( items => {
       if (items.length > maxItems) {
         cache.delete(items[0])
         .then(
           trimCache(cacheName, maxItems)
         ); // end delete then
       } // end if
     }); // end keys then
   }); // end open
 } // end function

See the problem? It’s right there at the start when I try to open the cache like this:

cacheName.open( cache => {

That won’t work. The open method only works on the caches object—I should be passing the name of the cache into the caches.open method. So the code should look like this:

caches.open( cacheName )
.then( cache => {

Everything else remains the same. The corrected trimCache function is here:

function trimCache(cacheName, maxItems) {
  caches.open(cacheName)
  .then( cache => {
    cache.keys()
    .then(items => {
      if (items.length > maxItems) {
        cache.delete(items[0])
        .then(
          trimCache(cacheName, maxItems)
        ); // end delete then
      } // end if
    }); // end keys then
  }); // end open then
} // end function

Sorry about that! I must’ve had some kind of brainfart when I was writing (and describing) that one line of code.

You may want to deface your copy of Going Offline by taking a pen to that code example. Normally I consider the practice of writing in books to be barbarism, but in this case …go for it.

Saturday, June 23rd, 2018

I discovered a browser bug - JakeArchibald.com

Jake’s blow-by-blow account of uncovering a serious browser vulnerability is fascinating. But if you don’t care for the technical details, skip ahead to to how different browser makers handled the issue—it’s very enlightening. (And if you do care for the technical details, make sure you click on the link to the PDF version of this post.)

Monday, April 30th, 2018

Apart From Code

A good developer…

  • debugs
  • follows the KISS principle (and respects YAGNI)
  • knows how to research
  • works well with others
  • finds good developer tools
  • tests code

Sunday, March 4th, 2018

The People Part of Design Systems – Related Works – Medium

I like the idea of “design bugs”:

Every two weeks or so, a group of designers would get together for a couple of hours to fix what we called “design bugs.” These were things that didn’t hinder functionality and wouldn’t have been filed as an engineering bug, but were places where we were using an old component, an existing one incorrectly, or a one-off alteration.

Monday, July 31st, 2017

rachelandrew/gridbugs: A curated list of Grid interop issues

Rachel is maintaining this (short) list of browser bugs with CSS Grid, inspired by the excellent Flexbugs.

Grid shipped into browsers](https://gridbyexample.com/browsers) in a highly interoperable state, however there are a few issues - let’s document any we find here.

Friday, July 21st, 2017

Patterns Day 2017: Rachel Andrew on Vimeo

Rachel’s fantastic talk from Patterns Day. There’s a lot of love for Fractal specifically, but there are also some great points about keeping a pattern library in sync with a live site, and treating individual components as reduced test-cases.

Patterns Day 2017: Rachel Andrew

Sunday, April 10th, 2016

A debugging thought process

Remy walks us through his performance debugging routine …and now Una must write him a song.

Wednesday, February 10th, 2016

Handling redirects with a Service Worker

When I wrote about implementing my first Service Worker, I finished with this plea:

And remember, please share your code and your gotchas: it’s early days for Service Workers so every implementation counts.

Well, I ran into a gotcha that was really frustrating but thanks to the generosity of others, I was able to sort it out.

It was all because of an issue in Chrome. Here’s the problem…

Let’s say you’ve got a Service Worker running that takes care of any requests to your site. Now on that site, you’ve got a URL that receives POST data, does something with it, and then redirects to another URL. That’s a fairly common situation—it’s how I handle webmentions here on adactio.com, and it’s how I handle most add/edit/delete actions over on The Session to help prevent duplicate form submissions.

Anyway, it turns out that Chrome’s Service Worker implementation would get confused by that. Instead of redirecting, it showed the offline page instead. The fetch wasn’t resolving.

I described the situation to Jake, but rather than just try and explain it in 140 characters, I built a test case.

There’s a Chromium issue filed on this, and it will get fixed, but it in the meantime, it was really bugging me recently when I was rolling out a new feature on The Session. Matthew pointed out that the Chromium bug report also contained a workaround that he’s been using on traintimes.org.uk. Adrian also posted his expanded workaround in there too. That turned out to be exactly what I needed.

I think the problem is that the redirect means that a body is included in the GET request, which is what’s throwing the Service Worker. So I need to create a duplicate request without the body:

request = new Request(url, {
    method: 'GET',
    headers: request.headers,
    mode: request.mode == 'navigate' ? 'cors' : request.mode,
    credentials: request.credentials,
    redirect: request.redirect
});

So here’s what I had in my Service Worker before:

// For HTML requests, try the network first, fall back to the cache, finally the offline page
if (request.headers.get('Accept').indexOf('text/html') !== -1) {
    event.respondWith(
        fetch(request)
            .then( response => {
                // NETWORK
                // Stash a copy of this page in the pages cache
                let copy = response.clone();
                stashInCache(pagesCacheName, request, copy);
                return response;
            })
            .catch( () => {
                // CACHE or FALLBACK
                return caches.match(request)
                    .then( response => response || caches.match('/offline') );
                })
        );
    return;
}

And here’s what I have now:

// For HTML requests, try the network first, fall back to the cache, finally the offline page
if (request.headers.get('Accept').indexOf('text/html') !== -1) {
    request = new Request(url, {
        method: 'GET',
        headers: request.headers,
        mode: request.mode == 'navigate' ? 'cors' : request.mode,
        credentials: request.credentials,
        redirect: request.redirect
    });
    event.respondWith(
        fetch(request)
            .then( response => {
                // NETWORK
                // Stash a copy of this page in the pages cache
                let copy = response.clone();
                stashInCache(pagesCacheName, request, copy);
                return response;
            })
            .catch( () => {
                // CACHE or FALLBACK
                return caches.match(request)
                    .then( response => response || caches.match('/offline') );
                })
        );
    return;
}

Now the test case is working just fine in Chrome.

On the off-chance that someone out there is struggling with the same issue, I hope that this is useful.

Share what you learn.

Friday, January 22nd, 2016

The Art of Debugging

I was just helping out with some debugging at work and it reminded me of this great talk/post by Remy:

  1. Replicate: see the bug
  2. Isolate: understand the bug
  3. Eliminate: fix the bug

Monday, December 7th, 2015

philipwalton/flexbugs

A list of known bugs (and workarounds) in flexbox implementations. This is going to be handy to refer back to.

Monday, November 16th, 2015

Online regex tester and debugger: JavaScript, Python, PHP, and PCRE

Regular expressions are my kryptonite. I’m rubbish at them and I can never keep the vocabulary in me head.

Mark recommended this tool so I’m going to give it a go the next time I have to resort to regex.

Friday, January 2nd, 2015

Taking Chrome DevTools outside of the browser. — Kenneth Auchenberg

Kenneth has isolated Chrome’s dev tools into its own app. This is a big step towards this goal:

Why are DevTools still bundled with the browsers? What if clicking “inspect element” simply started an external DevTools app?

With DevTools separated from one specific browser, a natural next step would be making the DevTools app work with other browsers.

Wednesday, April 23rd, 2014

webcompat.com

I like this idea. It would be nice to see it catch on…

  1. Report a bug for any website or browser.
  2. Our team of volunteers diagnoses the bug.
  3. We send a fix to the site owner or browser.

Friday, October 5th, 2012

iOS Six Fix

Last Christmas I gave you my bug report. Well, more of a whinge really. Scott put together a much better bug report and test page:

When the meta viewport tag is set to content=”width=device-width,initial-scale=1”, or any value that allows user-scaling, changing the device to landscape orientation causes the page to scale larger than 1.0. As a result, a portion of the page is cropped off the right, and the user must double-tap (sometimes more than once) to get the page to zoom properly into view.

Yes, it’s the old orientation and scale bug in Mobile Safari.

I’m pleased to report that as of iOS version 6, this bug seems to have finally been squashed. Hallelujah!

Given the relatively rapid upgrade path for iPhone, iPod Touch and iPad users, it won’t be long until we can remove our clever solutions for working around this problem.

Stand down, hackers, stand down. This bug has been taken care of.

Jeremy caught the mantis

Friday, March 23rd, 2012

scottjehl/Device-Bugs

Scott has created a one-stop-shop for documenting browser bugs in mobile devices. Feel free to add to it.

Wednesday, March 7th, 2012

Adobe Shadow | preview mobile web - Adobe Labs

Adobe have launched their version of Weinre, the tool that allows you to refresh and debug iOS and Android browser views from your desktop computer.