Troubleshooting — Integrations¶
Problems with the services the application depends on: AWS S3, SMTP e-mail, PDF rendering, SignalR, and two settings that act like integrations — the attendance IP allow-list and the global exchange rate. Background: External Services.
Uploads and downloads (S3)¶
Every document upload and download goes through S3ServiceHandler, which first finds the bucket and
folder for the feature:
| Symptom | Cause | Fix |
|---|---|---|
Invalid |
Storage has no entry for this feature's Functionality. |
Add it. All 19 values need an entry — see Configuration. |
| The same error on every asset-disposal upload | NKODestruction is missing from the example configuration, so every configuration built from it lacks it (R4-1). |
Add the NKODestruction entry. |
Amazon — Invalid, Signature or Access |
Wrong client / client, or the IAM user lacks rights on that bucket. The app still starts; it fails only on first use. |
Fix the credentials, or the bucket policy. |
Amazon — the bucket is in a different region |
Storage does not match the bucket. |
Use the bucket's region. |
| Upload of a large file fails before reaching the app | No upload limit is configured anywhere in the code, so the host default of 30,000,000 bytes (about 28.6 MB) applies. IIS rejects larger requests itself. | Larger files need a hosting change (max in the site's web.), and possibly an application change. |
No e-mail arrives¶
E-mail fails silently: both send methods in EmailManager wrap the SMTP call in an empty
catch (R1-6), so there is no error and no log. Work through these in order.
| # | Check | Why |
|---|---|---|
| 1 | SELECT Setting returns True |
Both send methods return without sending unless this row exists and parses as true. On a new database it does not exist (R5-5). |
| 2 | The recipient is an employee with login enabled | Approval notifications (the Send path) are sent only if an App has that exact Email and its login is enabled. Anyone else is skipped. |
| 3 | The server can reach smtp. on 587 |
The host and port are hard-coded in Email. |
| 4 | The sending mailbox's password is still valid | It is compiled into Site (R1-9). A password change needs a rebuild and redeploy, not a configuration change. |
| 5 | The mailbox may send through authenticated SMTP | Microsoft 365 can disable SMTP AUTH per mailbox or tenant. If it is off, every send fails — silently, here. |
To see the actual SMTP error, run the application locally with a debugger and break on thrown exceptions: the exception is raised, then swallowed.
Links in e-mails point to the wrong site
Notification links are built from SysUrl plus the page path, and several URLs are compiled into
SiteSettings.cs. A build made for one environment carries that environment's URLs (R4-4).
Check SysUrl first; if it is right, the build was made for another environment.
PDF export¶
PDFs are rendered by Rotativa, which runs wkhtmltopdf.exe from wwwroot\Rotativa\ as a separate
process.
| Symptom | Cause | Fix |
|---|---|---|
| Every PDF export fails on a new install | wwwroot\Rotativa\ is not in the repository and no binary ships (R5-3). |
Place the wkhtmltopdf binaries matching Rotativa.AspNetCore 1.2.0 there. |
| Every PDF export fails right after a publish | The IISProfile publish profile deletes files that are not in the package, including the binary (R4-3). |
Put the binary back, and publish with extra files kept. |
| Fails with an access-denied error | The app-pool identity cannot execute the binary. | Grant Read & execute on wwwroot\Rotativa\. |
| Jobs and Advance PDFs have no header or footer, or time out | Those exports make wkhtmltopdf fetch the header and footer from the site's own public HTTPS address. The server cannot reach itself, or wkhtmltopdf rejects the certificate. |
Allow the server to resolve and connect to its own host name ("hairpin"), and use a certificate it trusts — see Server Requirements. |
Real-time notifications¶
The top-bar badge and several exports use the SignalR hub at /hub.
| Symptom | Cause |
|---|---|
| Badges update only after a refresh | The browser cannot keep a connection to /. Check the browser console. Without the IIS WebSocket Protocol feature SignalR falls back to long polling, which still works but is slower. |
| Works for some users, not others | More than one worker process. SignalR has no backplane, so a message reaches only users on the same process (R4-5). |
| Nothing works, and links are broken too | The site is installed as an IIS sub-application. The client connects to the root-absolute /. |
| A warehouse or login-history export shows progress, then never offers the file | These exports run in the background — warehouse ones in Hangfire, login history in Quartz — and deliver the download link over SignalR. If the connection dropped, or the job ran on another process, the link never arrives. The file itself is written under C:\upload\…; check that folder exists (see Deployment). |
Attendance check-in rejected¶
Employees without Allow remote attendance can check in or out only from an allowed IP address.
The allowed list is CommonSetting row ips: a comma-separated list, compared as exact
strings. The messages are "You can't checkin/checkout on this IP address." on the home page and
"Not Authorized ChechIn Or CheckOut For IP : x" on the attendance screen. The second one shows the
address the server saw, so use it to diagnose.
| Cause | Check |
|---|---|
| The office's public address changed | Compare the address in the message with the list. |
| Spaces in the list | The value is split on , without trimming, so 1. never matches the second address. |
| A range was entered | Ranges and CIDR notation are not supported; list each address. |
| The site is behind a reverse proxy or load balancer | The address comes from Connection., and no forwarded-headers middleware is configured, so every user appears as the proxy's address. |
| IPv6 | A client reaching the server over IPv6 is compared by its IPv6 address. |
| Home page only: "Please upload your e-signature to activate check in/out." | The home-page check-in also requires an approved e-signature. |
To exempt an employee, set Allow remote attendance on their record (/HumanResource/EditEmp).
Exchange rates¶
There is no exchange-rate feed. The fixer.io client in the code is never called (R7-17), and
the global rate in ExchangeRates has no write path in the application (R7-1).
That rate converts TL and EUR purchase requests to USD, and the USD value decides which segregation-of-duties sign-offs a PR needs ($1 000, $5 000, $10 000, $100 000 thresholds). If no row is enabled, every TL/EUR PR is valued at $0 and skips all of them.
- The rates are USD per one unit of the currency, because the code computes
usd = amount × rate.TRYRateis therefore a small number (USD per 1 TL), not TL per USD. - Keep exactly one enabled row. The lookup takes the first enabled row with no ordering, so with several it is undefined which one is used.
- Payroll allocation and purchase-order lines use per-donor rates (
DonorExchangeRate, under Administration → Donors), not this table. If an allocation's recorded EUR rate equals its USD rate, that is R7-2: the audit column copies the wrong rate, although the EUR amount itself is computed correctly.