{"id":124182,"date":"2025-03-10T13:01:25","date_gmt":"2025-03-10T13:01:25","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/log-failed-google-analytics-requests-in-google-analytics\/"},"modified":"2025-03-10T13:01:25","modified_gmt":"2025-03-10T13:01:25","slug":"log-failed-google-analytics-requests-in-google-analytics","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=124182","title":{"rendered":"Log Failed Google Analytics Requests In Google Analytics"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<blockquote>\n<p><strong>READ THIS (26 Aug 2019)!!<\/strong> Unfortunately, the update I made in 2016 contained code that was incomplete and broken. I nevert noticed this until it was pointed out to me almost three years later. At this point, I don\u2019t have a working backup of the solution, so unless some internet archive \/ cache service manages to surface the code, this article is basically lost.<\/p>\n<\/blockquote>\n<p><em>UPDATE 20 December 2016: I made some fixes to the solution &#8211; be sure to grab the latest code snippet from below!<\/em><\/p>\n<p>Having worked in all sorts of <a href=\"https:\/\/analytics.google.com\/\">Google Analytics<\/a> projects over the years, I\u2019ve found myself more and more interested in the technical underpinnings of digital analytics rather than the actual analytical work. We all play to our respective strengths, I guess. For example, there are still many purely <em>technical \/ technological<\/em> mysteries surrounding Google Analytics, because much of the data processing is done server-side.<\/p>\n<p>One of these mysteries is a proper feedback loop for request quality. When you send a request to Google Analytics such as a Page View hit, you can verify that it works in multiple ways:<\/p>\n<p>I\u2019ve covered much of Google Analytics debugging in <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/debugging-tag-execution-properly\/\">this article<\/a>.<\/p>\n<p>However, no matter how successful your own tests are, one thing is missing: a solid, reliable way of collecting data from all failed requests from your site visitors. Google Analytics doesn\u2019t automatically log problems with data collection, even if <a href=\"https:\/\/support.google.com\/analytics\/answer\/6006306?hl=en\">Analytics notifications<\/a> do reveal some issues.<\/p>\n<p>This can, and should, lead to healthy doubt concerning the veracity of your data set &#8211; is it a representative sample of all hits sent from your digital property, or is some business critical information (such as Ecommerce) being dropped more than average?<\/p>\n<p>In this article, I want to show a simple way of logging all failed requests in Google Analytics as new events. The solution builds on <a href=\"http:\/\/www.seerinteractive.com\/about\/team\/stephen-harris\/\">Stephen Harris<\/a>\u2019 awesome <a href=\"https:\/\/www.simoahava.com\/analytics\/introducing-ga-spy-for-google-analytics\/\">GA Spy<\/a>, and the technical approach is encapsulated in a single Custom HTML Tag in <a href=\"https:\/\/tagmanager.google.com\/\">Google Tag Manager<\/a>.<\/p>\n<div style=\"aspect-ratio: 2762 \/ 1290;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/debug-duplicator.jpg\" title=\"debug-duplicator\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1290\" width=\"2762\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/debug-duplicator.jpg#ZgotmplZ\" alt=\"debug-duplicator\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Read on, my friend!<\/p>\n<p>                <span class=\"simmer\"><br \/>\n  <span class=\"close\">X<\/span><\/p>\n<p>\n    <span class=\"fa fa-md fa-bell\"\/><br \/>\n    <strong>The Simmer Newsletter<\/strong>\n  <\/p>\n<p>\n    Subscribe to the <a href=\"https:\/\/www.simoahava.com\/newsletter\/\">Simmer newsletter<\/a> to get the latest news and content from Simo Ahava into your email inbox!\n  <\/p>\n<p>  <\/span><\/p>\n<h2 id=\"the-solution\">The solution<\/h2>\n<p>Here\u2019s how it works.<\/p>\n<ol>\n<li>\n<p>GA Spy to processes every single call to the <code>ga()<\/code> global function.<\/p>\n<\/li>\n<li>\n<p>For each call with the <code>send<\/code> command, send the hit payload to <code>https:\/\/www.google-analytics.com\/debug\/collect<\/code> (<a href=\"https:\/\/www.simoahava.com\/analytics\/google-analytics-endpoint-debugger\/\">read more about the <code>\/debug\/<\/code> endpoint<\/a>).<\/p>\n<\/li>\n<li>\n<p>Don\u2019t forget to send the regular hit to Google Analytics.<\/p>\n<\/li>\n<li>\n<p>If the <code>\/debug\/<\/code> returns a failed request, push the error message and the failed hit payload into <code>dataLayer<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>In a nutshell, for every hit sent to Google Analytics, you\u2019re also sending the same hit to the GA debug endpoint. This endpoint returns information on whether or not the request was a success, and if it wasn\u2019t, what was wrong with it.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-json\" data-lang=\"json\">{\n  <span style=\"color:#1e90ff;font-weight:bold\">\"hitParsingResult\"<\/span>: [ {\n    <span style=\"color:#1e90ff;font-weight:bold\">\"valid\"<\/span>: <span style=\"color:#00a\">false<\/span>,\n    <span style=\"color:#1e90ff;font-weight:bold\">\"parserMessage\"<\/span>: [ {\n      <span style=\"color:#1e90ff;font-weight:bold\">\"messageType\"<\/span>: <span style=\"color:#a50\">\"WARN\"<\/span>,\n      <span style=\"color:#1e90ff;font-weight:bold\">\"description\"<\/span>: <span style=\"color:#a50\">\"The value provided for parameter 'ev' is invalid. Please see http:\/\/goo.gl\/a8d4RP#ev for details.\"<\/span>,\n      <span style=\"color:#1e90ff;font-weight:bold\">\"messageCode\"<\/span>: <span style=\"color:#a50\">\"VALUE_INVALID\"<\/span>,\n      <span style=\"color:#1e90ff;font-weight:bold\">\"parameter\"<\/span>: <span style=\"color:#a50\">\"ev\"<\/span>\n    } ],\n    <span style=\"color:#1e90ff;font-weight:bold\">\"hit\"<\/span>: <span style=\"color:#a50\">\"...\"<\/span>\n  } ],\n  <span style=\"color:#1e90ff;font-weight:bold\">\"parserMessage\"<\/span>: [ {\n    <span style=\"color:#1e90ff;font-weight:bold\">\"messageType\"<\/span>: <span style=\"color:#a50\">\"INFO\"<\/span>,\n    <span style=\"color:#1e90ff;font-weight:bold\">\"description\"<\/span>: <span style=\"color:#a50\">\"Found 1 hit in the request.\"<\/span>\n  } ]\n}<\/code><\/pre>\n<\/div>\n<p>From <code>dataLayer<\/code>, I\u2019m actually sending this information to Google Analytics via GTM. This way you\u2019ll end up with a report that looks like this:<\/p>\n<div style=\"aspect-ratio: 1416 \/ 454;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/error-messages.jpg\" title=\"Google Analytics error messages\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"454\" width=\"1416\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/error-messages.jpg#ZgotmplZ\" alt=\"Google Analytics error messages\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Heck, you can even click one of the error messages to drill down to the actual payloads. For example, if I choose <strong>\u2018ea\u2019<\/strong> error, I can see the payloads and verify that indeed, there\u2019s no Event Action parameter with these hits.<\/p>\n<div style=\"aspect-ratio: 1872 \/ 784;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/error-messages-details.jpg\" title=\"Error message details\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"784\" width=\"1872\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/error-messages-details.jpg#ZgotmplZ\" alt=\"Error message details\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>I can then go to GTM, find the offending tag, and fix it to always send some value in Event Action.<\/p>\n<p>Due to the abstraction of <code>dataLayer<\/code>, you don\u2019t have to log this information in Google Analytics. In fact, you might not <em>want<\/em> to, since you might already have some sort of logging rig setup in your development process. Thanks to Google Tag Manager, you can push the data to any endpoint that supports JavaScript-generated data transfer (e.g. HTTP requests).<\/p>\n<p>However, I\u2019ve elected to send the information to Google Analytics. Doing so, I can align these validation errors with all the other hits that this particular user has sent to GA, and I can thus potentially identify bigger issues that these validation errors might only be a symptom of. For example, it\u2019s possible that an Ecommerce tag only fails if the user has followed a specific funnel on the site. By sending the validation error to Google Analytics, I can see if it occurred during one of these broken funnels, giving me more information to fix it in the end.<\/p>\n<h2 id=\"how-to-do-it\">How to do it<\/h2>\n<p>You basically need a <strong>Custom HTML Tag<\/strong> that fires on the <strong>All Pages<\/strong> trigger, with a higher <a href=\"https:\/\/support.google.com\/tagmanager\/answer\/2772421?hl=en\">Tag Priority<\/a> than any of your Google Analytics tags that might also fire on this event.<\/p>\n<p>It\u2019s important that this code starts its execution before your Google Analytics tags have a chance to start up. This code overwrites the <code>ga()<\/code> method, and any tag that has already fired will not be debugged with this solution.<\/p>\n<p>You\u2019ll first need the actual code for GA Spy, and you can download the latest version from <a href=\"https:\/\/github.com\/smhmic\/ga-spy\/blob\/master\/ga-spy.js\">Stephen\u2019s repository<\/a>. You need to copy-paste the JavaScript into a Custom HTML Tag, and then add the custom listener below it. Here\u2019s the full example, where I\u2019ve minified the GA Spy code to make it more compact. Scroll down past the GA Spy part to find the actual magic.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-html\" data-lang=\"html\">script&gt;\n<span style=\"color:#aaa;font-style:italic\">\/* Minified GA Spy starts *\/<\/span>\n<span style=\"color:#0aa\">window<\/span>.gaSpy=<span style=\"color:#0aa\">window<\/span>.gaSpy||<span style=\"color:#00a\">function<\/span>(b){<span style=\"color:#00a\">var<\/span> j,k,c=<span style=\"color:#00a\">function<\/span>(a){<span style=\"color:#00a\">if<\/span>(b=<span style=\"color:#00a\">null<\/span>,a.debugLogPrefix=a.debugLogPrefix||<span style=\"color:#a50\">\"gaSpy\"<\/span>,!a.callback||<span style=\"color:#a50\">\"function\"<\/span>!=<span style=\"color:#00a\">typeof<\/span> a.callback)<span style=\"color:#00a\">throw<\/span> <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Error<\/span>(<span style=\"color:#a50\">\"[\"<\/span>+a.debugLogPrefix+<span style=\"color:#a50\">\"] Aborting; No listener callback provided.\"<\/span>);<span style=\"color:#00a\">return<\/span> a.gaObjName=a.gaObjName||<span style=\"color:#0aa\">window<\/span>.GoogleAnalyticsObject||<span style=\"color:#a50\">\"ga\"<\/span>,a.debug=!!a.debug,a}(<span style=\"color:#a50\">\"function\"<\/span>==<span style=\"color:#00a\">typeof<\/span> b?{callback:b}:b),d=c.gaObjName,e=<span style=\"color:#0aa\">window<\/span>[d],f=<span style=\"color:#0aa\">window<\/span>.console&amp;&amp;c.debug;?<span style=\"color:#00a\">function<\/span>(){<span style=\"color:#00a\">var<\/span> a=[].slice.call(arguments);a.unshift(<span style=\"color:#a50\">\"[\"<\/span>+c.debugLogPrefix+<span style=\"color:#a50\">\"]\"<\/span>),console.log.apply(console,a)}:<span style=\"color:#00a\">function<\/span>(){},g=<span style=\"color:#00a\">function<\/span>(a){<span style=\"color:#00a\">var<\/span> b,d={args:a,the:{}},e=d.the;<span style=\"color:#00a\">return<\/span> c.debug&amp;&amp;<span style=\"color:#00a\">function<\/span>;(b,c){<span style=\"color:#00a\">for<\/span>(b=<span style=\"color:#a50\">\"Intercepted: ga(\"<\/span>,c=<span style=\"color:#099\">0<\/span>;c1?b[<span style=\"color:#099\">0<\/span>]:<span style=\"color:#a50\">\"t0\"<\/span>,e.command=b.length&gt;<span style=\"color:#099\">1<\/span>?b[<span style=\"color:#099\">1<\/span>]:b[<span style=\"color:#099\">0<\/span>],b=b[b.length-<span style=\"color:#099\">1<\/span>].split(<span style=\"color:#a50\">\":\"<\/span>),e.pluginName=b.length&gt;<span style=\"color:#099\">1<\/span>?b[<span style=\"color:#099\">0<\/span>]:<span style=\"color:#00a\">void<\/span> <span style=\"color:#099\">0<\/span>,e.pluginMethodName=b.length&gt;<span style=\"color:#099\">1<\/span>?b[<span style=\"color:#099\">1<\/span>]:<span style=\"color:#00a\">void<\/span> <span style=\"color:#099\">0<\/span>,<span style=\"color:#a50\">\"require\"<\/span>===e.command||<span style=\"color:#a50\">\"provide\"<\/span>===e.command?(e.pluginName=a[<span style=\"color:#099\">1<\/span>],<span style=\"color:#a50\">\"provide\"<\/span>===e.command&amp;&amp;(e.pluginConstructor=a[<span style=\"color:#099\">2<\/span>])):(<span style=\"color:#a50\">\"send\"<\/span>===e.command&amp;&amp;(e.hitType=a[a.length-<span style=\"color:#099\">1<\/span>]&amp;&amp;a;[a.length-<span style=\"color:#099\">1<\/span>].hitType||a[<span style=\"color:#099\">1<\/span>]),<span style=\"color:#a50\">\"object\"<\/span>==<span style=\"color:#00a\">typeof<\/span> a[a.length-<span style=\"color:#099\">1<\/span>]&amp;&amp;(e.trackerName=a[a.length-<span style=\"color:#099\">1<\/span>].name||e.trackerName))),f(<span style=\"color:#a50\">\"Run listener callback\"<\/span>,e),!<span style=\"color:#099\">1<\/span>!==c.callback(d)},h=<span style=\"color:#00a\">function<\/span>(){<span style=\"color:#00a\">var<\/span> a=[].slice.call(arguments);<span style=\"color:#00a\">if<\/span>(c.debug){<span style=\"color:#00a\">if<\/span>(!g(a))<span style=\"color:#00a\">return<\/span> f(<span style=\"color:#a50\">\"Command blocked.\"<\/span>)}<span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">try<\/span>{<span style=\"color:#00a\">if<\/span>(!g(a))<span style=\"color:#00a\">return<\/span>}<span style=\"color:#00a\">catch<\/span>(a){}<span style=\"color:#00a\">return<\/span> f(<span style=\"color:#a50\">\"Command allowed:\"<\/span>,a),h._gaOrig.apply(h._gaOrig,a)},i=<span style=\"color:#00a\">function<\/span>(){<span style=\"color:#00a\">var<\/span> a,b=h._gaOrig=<span style=\"color:#0aa\">window<\/span>[d];f(<span style=\"color:#a50\">\"Hijack\"<\/span>,b._gaOrig?<span style=\"color:#a50\">\"(already hijacked)\"<\/span>:<span style=\"color:#a50\">\"\"<\/span>),<span style=\"color:#0aa\">window<\/span>[d]=h;<span style=\"color:#00a\">for<\/span>(a <span style=\"color:#00a\">in<\/span> b)b.hasOwnProperty(a)&amp;&amp;(<span style=\"color:#0aa\">window<\/span>[d][a]=b[a])};<span style=\"color:#00a\">if<\/span>(f(<span style=\"color:#a50\">\"Config:\"<\/span>,c),e||(f(<span style=\"color:#a50\">\"Instantiate GA command queue\"<\/span>),e=<span style=\"color:#0aa\">window<\/span>[d]=<span style=\"color:#00a\">function<\/span>(){(<span style=\"color:#0aa\">window<\/span>[d].q=<span style=\"color:#0aa\">window<\/span>[d].q||[]).push(arguments)},e.l=<span style=\"color:#099\">1<\/span>*<span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Date<\/span>),e.getAll)f(<span style=\"color:#a50\">\"GA already loaded; cannot see previous commands\"<\/span>),i();<span style=\"color:#00a\">else<\/span>{<span style=\"color:#00a\">if<\/span>(!e.l)<span style=\"color:#00a\">throw<\/span> <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Error<\/span>(<span style=\"color:#a50\">\"[\"<\/span>+c.debugLogPrefix+<span style=\"color:#a50\">\"] Aborting; `\"<\/span>+d+<span style=\"color:#a50\">\"` not the GA object.\"<\/span>);<span style=\"color:#00a\">if<\/span>(f(<span style=\"color:#a50\">\"Command queue instantiated, but library not yet loaded\"<\/span>),e.q&amp;&amp;e.q.length;){<span style=\"color:#00a\">for<\/span>(f(<span style=\"color:#a50\">\"Applying listener to\"<\/span>,e.q.length,<span style=\"color:#a50\">\" queued commands\"<\/span>),j=[],k=<span style=\"color:#099\">0<\/span>;k -<span style=\"color:#099\">1<\/span>; })[<span style=\"color:#099\">0<\/span>]\n                               .description;\n      <span style=\"color:#00a\">var<\/span> errorHit = data.hitParsingResult[<span style=\"color:#099\">0<\/span>].hit;\n      <span style=\"color:#0aa\">window<\/span>.dataLayer.push({\n        event: <span style=\"color:#a50\">'gaValidationError'<\/span>,\n        gaValidationError: {\n          description: errorDescription,\n          hit: errorHit\n        }\n      });\n    };\n    \n    <span style=\"color:#aaa;font-style:italic\">\/\/ If a 'send' command is registered, start the process\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">if<\/span> (<span style=\"color:#00a\">typeof<\/span> ga === <span style=\"color:#a50\">'function'<\/span> &amp;&amp; trackerName &amp;&amp; gaCommand === <span style=\"color:#a50\">'send'<\/span>) {\n      ga(<span style=\"color:#00a\">function<\/span>() {\n        tracker = ga.getByName(trackerName);\n        <span style=\"color:#00a\">if<\/span> (!tracker.get(<span style=\"color:#a50\">'debugDone'<\/span>)) {\n          originalSendTask = tracker.get(<span style=\"color:#a50\">'sendHitTask'<\/span>);\n          tracker.set(<span style=\"color:#a50\">'sendHitTask'<\/span>, buildDebugHit);\n        }\n      });\n    }\n  } <span style=\"color:#00a\">catch<\/span>(e) {\n    <span style=\"color:#aaa;font-style:italic\">\/\/ Error handling\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  }\n});\n<span style=\"color:#1e90ff;font-weight:bold\">script<\/span>&gt;<\/code><\/pre>\n<\/div>\n<p>This solution uses <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/analyticsjs\/tasks\">Universal Analytics Tasks API<\/a> to copy the hit payload sent to Google Analytics, and to send it then to the debugger endpoint.<\/p>\n<p>Since you\u2019re actually \u201chijacking\u201d Google Analytics here, it\u2019s very important that <strong>you test this thoroughly<\/strong>. To see if it works, you should see a POST request to \/debug\/collect for each actual hit to \/collect. You can find this in the Network debugger of your browser\u2019s developer tools. Here\u2019s what the output looks like in Chrome:<\/p>\n<div style=\"aspect-ratio: 1256 \/ 878;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/network-debugger.jpg\" title=\"Network debugger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"878\" width=\"1256\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/network-debugger.jpg#ZgotmplZ\" alt=\"Network debugger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Again, remember to test it.<\/p>\n<h4 id=\"send-the-information-to-google-analytics\">Send the information to Google Analytics<\/h4>\n<p>To send the validation error hits to Google Analytics, you\u2019ll need a <strong>Universal Analytics tag<\/strong>, two <strong>Data Layer variables<\/strong> and a <strong>Custom Event trigger<\/strong>.<\/p>\n<p>The <strong>Data Layer variables<\/strong> should point to variable names <code>gaValidationError.description<\/code> and <code>gaValidationError.hit<\/code>. They might thus look something like this:<\/p>\n<div style=\"aspect-ratio: 1984 \/ 738;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/data-layer-variables.jpg\" title=\"Data Layer Variables\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"738\" width=\"1984\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/data-layer-variables.jpg#ZgotmplZ\" alt=\"Data Layer Variables\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Next, the <strong>Custom Event Trigger<\/strong> is a simple affair, and looks like this:<\/p>\n<div style=\"aspect-ratio: 666 \/ 712;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/custom-event-trigger.jpg\" title=\"Custom Event Trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"712\" width=\"666\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/custom-event-trigger.jpg#ZgotmplZ\" alt=\"Custom Event Trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Finally, the <strong>Universal Analytics tag<\/strong> is your run-of-the-mill Event tag, with just one important modification. You need to set a custom <strong>Fields to set<\/strong> field to:<\/p>\n<p><strong>Field name:<\/strong> debugDone<br \/><strong>Value:<\/strong> true<\/p>\n<p>Don\u2019t bother looking it up in the <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/analyticsjs\/field-reference\">supported field reference for analytics.js<\/a>, it\u2019s not there. It\u2019s a custom field I created only for this solution. It prevents two things: 1) Calls to the debug endpoint from multiplying when the same tracker is used, and 2) calls to the debug endpoint for the validation error events.<\/p>\n<p>Here\u2019s what the Event tag might look like:<\/p>\n<div style=\"aspect-ratio: 2362 \/ 1496;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2016\/12\/event-tag.jpg\" title=\"Universal Analytics Event Tag\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1496\" width=\"2362\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2016\/12\/event-tag.jpg#ZgotmplZ\" alt=\"Universal Analytics Event Tag\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>This particular tag will send each validation error as a <a href=\"https:\/\/support.google.com\/analytics\/answer\/1033068#NonInteractionEvents\"><em>non-interaction event<\/em><\/a> to Google Analytics, with the error description as the Event Action and the broken hit payload as the Event Label.<\/p>\n<h2 id=\"summary\">Summary<\/h2>\n<p>This solution relies on the awesomeness of <a href=\"https:\/\/www.simoahava.com\/analytics\/introducing-ga-spy-for-google-analytics\/\">GA Spy<\/a>. The script basically hijacks the GA global method, and copies all commands to the debug endpoint.<\/p>\n<p>What this solution does is give you yet another tool for validating your Google Analytics setup. When working with complex Google Tag Manager setups, it might be difficult to keep tabs on all the variables you are using. This might lead to problems in your tags, when a required field ends up with a blank value just because a variable didn\u2019t resolve in an expected way. This solution lets you find these cases with ease, giving you a clear path to fixing them before they become a real data quality problem.<\/p>\n<p>It would be pretty neat to have the <code>\/debug\/<\/code> interface as a tool you could install locally. That way you wouldn\u2019t need to do the trip to Google Analytics servers, and instead validate the hits in your own web server. On the other hand, the logic isn\u2019t probably that complex, so having it as a dedicated JavaScript library would be great as well. In any case, the endpoint debugger is a really smooth tool, especially when combined with GA Spy as illustrated in this article.<\/p>\n<p>Another thing that would make this whole thing easier was if the original request to <code>\/collect<\/code> simply returned the debug payload automatically. That way you could just look at the responses to the GA requests without having to do the extra trip to <code>\/debug\/<\/code>. I understand this doesn\u2019t exist because of latency and how most hits to GA are still done with a GET request. Still, Google could at least make it a configurable setting in the GA request.<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>READ THIS (26 Aug 2019)!! Unfortunately, the update I made in 2016 contained code that was incomplete and broken. I nevert noticed this until it was pointed out to me almost three years later. At this point, I don\u2019t have a working backup of the solution, so unless some internet archive \/ cache service manages [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":124183,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[12765,21623,1531,3605,24618],"dealstore":[],"offerexpiration":[],"class_list":["post-124182","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-analytics","tag-failed","tag-google","tag-log","tag-requests"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Log Failed Google Analytics Requests In Google Analytics - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=124182\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Log Failed Google Analytics Requests In Google Analytics - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"READ THIS (26 Aug 2019)!! Unfortunately, the update I made in 2016 contained code that was incomplete and broken. I nevert noticed this until it was pointed out to me almost three years later. At this point, I don\u2019t have a working backup of the solution, so unless some internet archive \/ cache service manages [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=124182\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-10T13:01:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1196\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=124182#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=124182\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Log Failed Google Analytics Requests In Google Analytics\",\"datePublished\":\"2025-03-10T13:01:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=124182\"},\"wordCount\":1427,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=124182#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg\",\"keywords\":[\"Analytics\",\"Failed\",\"Google\",\"Log\",\"Requests\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=124182#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=124182\",\"url\":\"https:\/\/fivemor.com\/?p=124182\",\"name\":\"Log Failed Google Analytics Requests In Google Analytics - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=124182#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=124182#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg\",\"datePublished\":\"2025-03-10T13:01:25+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=124182#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=124182\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=124182#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg\",\"width\":2560,\"height\":1196},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=124182#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Log Failed Google Analytics Requests In Google Analytics\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Log Failed Google Analytics Requests In Google Analytics - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=124182","og_locale":"en_US","og_type":"article","og_title":"Log Failed Google Analytics Requests In Google Analytics - Som2ny Network","og_description":"READ THIS (26 Aug 2019)!! Unfortunately, the update I made in 2016 contained code that was incomplete and broken. I nevert noticed this until it was pointed out to me almost three years later. At this point, I don\u2019t have a working backup of the solution, so unless some internet archive \/ cache service manages [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=124182","og_site_name":"Som2ny Network","article_published_time":"2025-03-10T13:01:25+00:00","og_image":[{"width":2560,"height":1196,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=124182#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=124182"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Log Failed Google Analytics Requests In Google Analytics","datePublished":"2025-03-10T13:01:25+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=124182"},"wordCount":1427,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=124182#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg","keywords":["Analytics","Failed","Google","Log","Requests"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=124182#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=124182","url":"https:\/\/fivemor.com\/?p=124182","name":"Log Failed Google Analytics Requests In Google Analytics - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=124182#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=124182#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg","datePublished":"2025-03-10T13:01:25+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=124182#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=124182"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=124182#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/debug-duplicator-scaled.jpg","width":2560,"height":1196},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=124182#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Log Failed Google Analytics Requests In Google Analytics"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/124182","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=124182"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/124182\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/124183"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=124182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=124182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=124182"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=124182"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=124182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}