<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dk Usa</title>
    <description>The latest articles on DEV Community by Dk Usa (@bairescodeai).</description>
    <link>https://dev.to/bairescodeai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3948401%2F98816c77-ca7e-4c8d-aa39-afb1c4f8ac3c.png</url>
      <title>DEV Community: Dk Usa</title>
      <link>https://dev.to/bairescodeai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bairescodeai"/>
    <language>en</language>
    <item>
      <title>React.lazy + chunk errors: how to recover users stuck after a deploy</title>
      <dc:creator>Dk Usa</dc:creator>
      <pubDate>Sun, 24 May 2026 16:11:18 +0000</pubDate>
      <link>https://dev.to/bairescodeai/reactlazy-chunk-errors-how-to-recover-users-stuck-after-a-deploy-2o38</link>
      <guid>https://dev.to/bairescodeai/reactlazy-chunk-errors-how-to-recover-users-stuck-after-a-deploy-2o38</guid>
      <description>&lt;p&gt;Classic React production bug: you deploy a new bundle, user has the old HTML cached in their tab, they navigate to a route → &lt;code&gt;React.lazy()&lt;/code&gt; tries to import a chunk that no longer exists on the CDN → blank screen.&lt;br&gt;
The error in the console looks like:&lt;br&gt;
Failed to fetch dynamically imported module:&lt;br&gt;
&lt;a href="https://cdn.example.com/assets/Page-abc123.js" rel="noopener noreferrer"&gt;https://cdn.example.com/assets/Page-abc123.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The user has no way out except hard-reload, and most don't know that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;p&gt;A global &lt;code&gt;error&lt;/code&gt; listener that catches chunk load errors and force-reloads the page with a cache-bust param:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
js
const CHUNK_ERROR_PATTERNS = [
  /Loading chunk \d+ failed/i,
  /Failed to fetch dynamically imported module/i,
  /Loading CSS chunk .* failed/i,
  /Importing a module script failed/i,
];
window.addEventListener('error', (e) =&amp;gt; {
  const msg = e?.message || '';
  if (CHUNK_ERROR_PATTERNS.some(rx =&amp;gt; rx.test(msg))) {
    const url = new URL(window.location.href);
    url.searchParams.set('_r', String(Date.now()));
    window.location.replace(url.toString());
  }
});
Why each part matters:

Multiple patterns: different browsers throw different messages. Safari uses "Importing a module script failed", Chrome uses "Failed to fetch dynamically imported module", older Webpack builds use "Loading chunk N failed".
Case insensitive: some browsers capitalize, some don't.
Cache-bust param: ?_r=&amp;lt;timestamp&amp;gt; forces fresh index.html, which has the new chunk hashes.
replace() not assign(): doesn't add a history entry, so back button works.
Gotchas
This catches unhandledrejection too if the lazy import throws inside a promise. Add a second listener if you see misses.
Don't trigger reload more than once: add a flag to avoid loops on a network outage.
Test it: deploy a new build, open the old tab, navigate. Should auto-recover.
It's 15 lines but saved me a real percentage of users abandoning the app post-deploy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Infinite recursion in Postgres RLS: a SECURITY DEFINER gotcha</title>
      <dc:creator>Dk Usa</dc:creator>
      <pubDate>Sun, 24 May 2026 15:04:29 +0000</pubDate>
      <link>https://dev.to/bairescodeai/infinite-recursion-in-postgres-rls-a-security-definer-gotcha-1916</link>
      <guid>https://dev.to/bairescodeai/infinite-recursion-in-postgres-rls-a-security-definer-gotcha-1916</guid>
      <description>&lt;p&gt;Spent a few hours yesterday on what looked like a haunted Postgres bug. Sharing the fix in case someone else hits it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;I had a multi-tenant app with a &lt;code&gt;profiles&lt;/code&gt; table. I wanted "team admins can see all team profiles". Naive policy:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sql
CREATE POLICY "admin_sees_team"
    ON public.profiles FOR SELECT
    TO authenticated
    USING (
        team_id IS NOT NULL
        AND EXISTS (
            SELECT 1 FROM public.profiles me
            WHERE me.id = auth.uid()
              AND me.role = 'admin'
        )
    );
Looks innocent, right?

The bug
Every query against profiles returned:

ERROR: 42P17: infinite recursion detected in policy for relation "profiles"
The policy's EXISTS subquery hits profiles — which triggers the policy again — which hits profiles again. Postgres detects it and bails.

The fix that didn't work
My first attempt: extract the check into a SQL function with SECURITY DEFINER.

CREATE FUNCTION is_admin(uid uuid) RETURNS boolean AS $$
    SELECT EXISTS (
        SELECT 1 FROM profiles WHERE id = uid AND role = 'admin'
    );
$$ LANGUAGE sql STABLE SECURITY DEFINER;
Still recursed. Why? Postgres inlines simple SQL functions during query planning. When inlined, the SECURITY DEFINER context is lost and RLS applies to the inner query → recursion is back.

The fix that worked
Use LANGUAGE plpgsql instead. plpgsql functions are never inlined:

CREATE OR REPLACE FUNCTION is_admin(uid uuid)
RETURNS boolean
LANGUAGE plpgsql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
BEGIN
    RETURN EXISTS (
        SELECT 1 FROM profiles
        WHERE id = uid AND role = 'admin'
    );
END;
$$;
Then the policy:

CREATE POLICY "admin_sees_team"
    ON profiles FOR SELECT
    TO authenticated
    USING (team_id IS NOT NULL AND is_admin(auth.uid()));
No more recursion. The plpgsql wrapper preserves the SECURITY DEFINER context, the subquery runs as the function owner (postgres), and RLS doesn't apply.

Takeaway
When a RLS policy needs to query its own table:

Don't use a raw subquery — recursion.
SQL functions look like a fix but get inlined.
plpgsql functions with SECURITY DEFINER are the only safe way.
Hope this saves someone the 3 hours I lost.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>postgres</category>
      <category>supabase</category>
      <category>webdev</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
