<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Edge Apps library 1.1.0 | Screenly</title><description>What has shipped across Screenly, newest first.</description><link>https://www.screenly.io/releases/edge-apps/1.1.0/</link><language>en</language><atom:link href="https://www.screenly.io/releases/edge-apps/1.1.0/rss.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate><item><title>Edge Apps library 1.1.0: Edge Apps can send their errors to your own Sentry project</title><link>https://www.screenly.io/releases/edge-apps/1.1.0/sentry-error-reporting/</link><guid isPermaLink="true">https://www.screenly.io/releases/edge-apps/1.1.0/sentry-error-reporting/</guid><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><category>release</category><category>developers</category><description>&lt;p&gt;An Edge App that fails on a screen in another building usually fails quietly. Nobody is standing in
front of it with the developer tools open. With &lt;code&gt;setupSentry()&lt;/code&gt; and &lt;code&gt;reportError()&lt;/code&gt;, those errors
land in your own Sentry project instead, with enough context to tell which screen sent them.&lt;/p&gt;
&lt;p&gt;Add a &lt;code&gt;sentry_dsn&lt;/code&gt; setting to &lt;code&gt;screenly.yml&lt;/code&gt;, set it to your project&amp;rsquo;s DSN in Screenly, and call
&lt;code&gt;setupSentry()&lt;/code&gt; once when the app starts:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;button type="button" class="code-copy" aria-label="Copy code" data-copy-code&gt;
&lt;svg data-copy viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;rect x="9" y="9" width="11" height="11" rx="2"&gt;&lt;/rect&gt;
&lt;path d="M5 15V5a2 2 0 0 1 2-2h10"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;svg data-check viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;/button&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;settings&lt;/span&gt;:&lt;span style="color:#666"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;sentry_dsn&lt;/span&gt;:&lt;span style="color:#666"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;type&lt;/span&gt;:&lt;span style="color:#666"&gt; &lt;/span&gt;secret&lt;span style="color:#666"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;title&lt;/span&gt;:&lt;span style="color:#666"&gt; &lt;/span&gt;Sentry Client Key&lt;span style="color:#666"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;optional&lt;/span&gt;:&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;true&lt;/span&gt;&lt;span style="color:#666"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;is_global&lt;/span&gt;:&lt;span style="color:#666"&gt; &lt;/span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="code-block"&gt;
&lt;button type="button" class="code-copy" aria-label="Copy code" data-copy-code&gt;
&lt;svg data-copy viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;rect x="9" y="9" width="11" height="11" rx="2"&gt;&lt;/rect&gt;
&lt;path d="M5 15V5a2 2 0 0 1 2-2h10"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;svg data-check viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M20 6 9 17l-5-5"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;/button&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;import&lt;/span&gt; { setupSentry, reportError } &lt;span style="color:#6ab825;font-weight:bold"&gt;from&lt;/span&gt; &lt;span style="color:#ed9d13"&gt;&amp;#39;@screenly/edge-apps&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;setupSentry(&lt;span style="color:#ed9d13"&gt;&amp;#39;menu-board&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6ab825;font-weight:bold"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#6ab825;font-weight:bold"&gt;await&lt;/span&gt; refreshPrices()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#6ab825;font-weight:bold"&gt;catch&lt;/span&gt; (error) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reportError(error, { source: &lt;span style="color:#ed9d13"&gt;&amp;#39;price-feed&amp;#39;&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Every event is tagged with &lt;code&gt;edge_app&lt;/code&gt; (the name you pass) and the screen&amp;rsquo;s &lt;code&gt;hostname&lt;/code&gt;, which is
also set as the Sentry user, so one screen&amp;rsquo;s errors group together. The optional second argument
to &lt;code&gt;setupSentry()&lt;/code&gt; attaches contexts of your own, such as the URL a report was embedded from. The
second argument to &lt;code&gt;reportError()&lt;/code&gt; goes in as extra data on that event.&lt;/p&gt;
&lt;p&gt;Before an event leaves the screen, the value of any setting whose key contains &lt;code&gt;token&lt;/code&gt;, &lt;code&gt;secret&lt;/code&gt;,
&lt;code&gt;password&lt;/code&gt;, or &lt;code&gt;credential&lt;/code&gt; is replaced with &lt;code&gt;[REDACTED]&lt;/code&gt; wherever it appears in the event. If an
event can&amp;rsquo;t be checked that way, it isn&amp;rsquo;t sent. The same filter is exported as
&lt;code&gt;scrubSensitiveData()&lt;/code&gt; if you initialize Sentry yourself and want it as your &lt;code&gt;beforeSend&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Leave &lt;code&gt;sentry_dsn&lt;/code&gt; empty and &lt;code&gt;setupSentry()&lt;/code&gt; does nothing, so the same build runs with or without
error reporting. It reports errors only, with no performance tracing.&lt;/p&gt;</description></item></channel></rss>