[Bug]: unclean handling of SimpleFIN downtime #1554

Open
opened 2026-02-28 19:47:04 -06:00 by GiteaMirror · 3 comments
Owner

Originally created by @chrwei on GitHub (Nov 1, 2024).

Verified issue does not already exist?

  • I have searched and found no existing issue
  • I will be providing steps how to reproduce the bug (in most cases this will also mean uploading a demo budget file)

What happened?

Trying to sync banks and I get the error "This account is experiencing connection problems. Let’s fix it." Clicking that give the details "An internal error occurred. Try to login again, or get in touch for support." and the option to unlink the account. I didn't try it but i think this would also fail.

Using this test script https://gist.github.com/duplaja/4df7e47230566894b7ee2a7e45ac2f50 also errors, and the "pickle" file contains HTML with title tag "Temporary Maintenance - SimpleFIN Bridge" and a messages section stating "This website is undergoing temporary maintenance. Some functions are unavailable at this time."

Ideally, Actual would check the SimpleFIN return and show that message instead of offering to unlink.

Where are you hosting Actual?

Docker

What browsers are you seeing the problem on?

Chrome

Operating System

Windows 11

Originally created by @chrwei on GitHub (Nov 1, 2024). ### Verified issue does not already exist? - [X] I have searched and found no existing issue - [X] I will be providing steps how to reproduce the bug (in most cases this will also mean uploading a demo budget file) ### What happened? Trying to sync banks and I get the error "This account is experiencing connection problems. Let’s fix it." Clicking that give the details "An internal error occurred. Try to login again, or get [in touch](https://actualbudget.org/contact/) for support." and the option to unlink the account. I didn't try it but i think this would also fail. Using this test script https://gist.github.com/duplaja/4df7e47230566894b7ee2a7e45ac2f50 also errors, and the "pickle" file contains HTML with title tag "Temporary Maintenance - SimpleFIN Bridge" and a messages section stating "This website is undergoing temporary maintenance. Some functions are unavailable at this time." Ideally, Actual would check the SimpleFIN return and show that message instead of offering to unlink. ### Where are you hosting Actual? Docker ### What browsers are you seeing the problem on? Chrome ### Operating System Windows 11
GiteaMirror added the bank syncbug labels 2026-02-28 19:47:04 -06:00
Author
Owner

@chrwei commented on GitHub (Nov 1, 2024):

full html returned by SimpleFIN:

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="Description" content="The SimpleFIN Bridge lets you securely share your financial transaction data with apps.">
    <title>Temporary Maintenance - SimpleFIN Bridge</title>
    <link rel="stylesheet" href="/static/wing.css" />
    <link rel="stylesheet" href="/static/style.css" />
    <link rel="icon" href="/static/favicon.png" type="image/png" /> 
  </head>
  <body>
    <section class="container main-wrapper">
      
      <section class="main-document">
      <header class="nav left">
        <div class="nav-item logo-holder">
          <img src="/static/logo.svg" class="logo" alt="SimpleFIN Logo"/>
          SimpleFIN Bridge
        </div>
        <div class="nav-item">
          <a href="/">Home</a>
        </div>
        <div class="nav-item">
          <a href="/auth/login">Sign in</a>
        </div>
      </header>
      
      <section class="messages" id="messages-section">
      <div class="message warning">
        <span>This website is undergoing temporary maintenance. Some functions are unavailable at this time.</span>
      </div>

      </section>
      <script>
        function isVisible(elem) {
          let bounds = elem.getBoundingClientRect();
          return bounds.top > 0 && bounds.bottom < window.innerHeight;
        }
        function flashMessage(message, cls) {
          let div = document.createElement('div');
          div.classList.add('message');
          if (cls) {
            div.classList.add(cls);
          }
          let span = document.createElement('span');
          span.innerText = message;
          div.appendChild(span);
          div.innerHTML += `<a href="javascript:void(0);" onclick="this.parentNode.parentNode.removeChild(this.parentNode); return false;">(dismiss)</a>`;
          document.getElementById('messages-section').appendChild(div);
          if (!isVisible(div)) {
            div.scrollIntoView && div.scrollIntoView({
              behavior: 'smooth',
            });
          }
        }
      </script>
      
      <section class="main">
        <h1>Temporary Maintenance</h1>
        <p>
  This site is currently undergoing temporary maintenance. Some functions will be unavailable until the maintenance is complete.
</p>
      </section>

    </section>

    <footer>
      <div class="footer-nav">
        <a href="/search-institutions">Supported institutions</a>
        <a href="/info/developers">Developer guide</a>
        <a href="/info/mission">Our mission</a>
        <a href="/info/terms">Terms of Use</a>
        <a href="/info/privacy">Privacy</a>
        <a href="/info/security">Security</a>
        <a href="/info/contact">Contact us</a>
      </div>
      <p class="copyright">Copyright &copy; SimpleFIN</p>
    </footer>
    </section>
  </body>
</html>
@chrwei commented on GitHub (Nov 1, 2024): full html returned by SimpleFIN: ``` <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="Description" content="The SimpleFIN Bridge lets you securely share your financial transaction data with apps."> <title>Temporary Maintenance - SimpleFIN Bridge</title> <link rel="stylesheet" href="/static/wing.css" /> <link rel="stylesheet" href="/static/style.css" /> <link rel="icon" href="/static/favicon.png" type="image/png" /> </head> <body> <section class="container main-wrapper"> <section class="main-document"> <header class="nav left"> <div class="nav-item logo-holder"> <img src="/static/logo.svg" class="logo" alt="SimpleFIN Logo"/> SimpleFIN Bridge </div> <div class="nav-item"> <a href="/">Home</a> </div> <div class="nav-item"> <a href="/auth/login">Sign in</a> </div> </header> <section class="messages" id="messages-section"> <div class="message warning"> <span>This website is undergoing temporary maintenance. Some functions are unavailable at this time.</span> </div> </section> <script> function isVisible(elem) { let bounds = elem.getBoundingClientRect(); return bounds.top > 0 && bounds.bottom < window.innerHeight; } function flashMessage(message, cls) { let div = document.createElement('div'); div.classList.add('message'); if (cls) { div.classList.add(cls); } let span = document.createElement('span'); span.innerText = message; div.appendChild(span); div.innerHTML += `<a href="javascript:void(0);" onclick="this.parentNode.parentNode.removeChild(this.parentNode); return false;">(dismiss)</a>`; document.getElementById('messages-section').appendChild(div); if (!isVisible(div)) { div.scrollIntoView && div.scrollIntoView({ behavior: 'smooth', }); } } </script> <section class="main"> <h1>Temporary Maintenance</h1> <p> This site is currently undergoing temporary maintenance. Some functions will be unavailable until the maintenance is complete. </p> </section> </section> <footer> <div class="footer-nav"> <a href="/search-institutions">Supported institutions</a> <a href="/info/developers">Developer guide</a> <a href="/info/mission">Our mission</a> <a href="/info/terms">Terms of Use</a> <a href="/info/privacy">Privacy</a> <a href="/info/security">Security</a> <a href="/info/contact">Contact us</a> </div> <p class="copyright">Copyright &copy; SimpleFIN</p> </footer> </section> </body> </html> ```
Author
Owner

@psybers commented on GitHub (Nov 3, 2024):

Any idea what HTTP code they returned while in maintenance? If it returns a 200 with that body, then it might be harder to deal with. But if it used another code then we can easily detect and provide a custom message.

@psybers commented on GitHub (Nov 3, 2024): Any idea what HTTP code they returned while in maintenance? If it returns a 200 with that body, then it might be harder to deal with. But if it used another code then we can easily detect and provide a custom message.
Author
Owner

@chrwei commented on GitHub (Nov 3, 2024):

the script didn't log that and I didn't think to add it. I've had to do this with other APIs though, it's as simple as checking the first character of the response text to make sure it's json and not html. parsing the html for the message is the harder part, but even just showing the title tag contents would be enough for most cases I think

@chrwei commented on GitHub (Nov 3, 2024): the script didn't log that and I didn't think to add it. I've had to do this with other APIs though, it's as simple as checking the first character of the response text to make sure it's json and not html. parsing the html for the message is the harder part, but even just showing the title tag contents would be enough for most cases I think
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#1554