跪拜 Guibai
← All articles
Frontend · Backend · Interview

A Frontend Developer's Guide to Backend Troubleshooting: curl, traceId, Logs, MySQL, and Redis

By swipe ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Frontend engineers who can isolate a backend fault to a specific layer—rather than reporting a vague page error—cut cross-team debugging time dramatically and gain the confidence to fix server-side issues themselves.

Summary

Frontend debugging habits—checking the Network panel, console logs, and page state—are a starting point but insufficient for backend systems where failures can originate in security filters, parameter binding, transactions, or cache layers. A reliable troubleshooting loop starts by reproducing the issue with curl to eliminate browser noise, then reads the unified ApiResponse.code and traceId before stepping through Controller, Facade, DbService, MySQL, and Redis.

HTTP status codes alone are ambiguous: a 404 can mean a missing route or a deliberately hidden business object, and a 409 signals a state conflict that should not be blindly retried. The traceId, generated or passed through by a servlet filter, ties a single request to server-side logs and is the most valuable piece of data a frontend team can attach to a bug report.

Concrete practices include using docker exec to inspect MySQL and Redis directly, reading test names as executable business-rule documentation, and turning every production bug into a minimal reproduction test. The core shift is from asking "why is the page wrong" to identifying exactly which layer of the backend chain first diverged from the expected behavior.

Takeaways
Reproduce every backend issue with curl first to eliminate browser, CORS, and frontend-state variables.
Read ApiResponse.code, not the human-readable message; business codes are stable and safe for frontend branching.
Attach the traceId from the response header or body to every bug report so backend engineers can search logs instantly.
Distinguish 400 (validation/JSON), 401 (unauthenticated), 403 (authenticated but forbidden), 404 (route vs. resource), 409 (state conflict), and 500 (unhandled server error) by checking both HTTP status and business code.
Step through the chain in order: confirm the Controller was entered, then check the Facade branch, then the DbService affected rows, then MySQL, then Redis.
Use docker exec to query MySQL and Redis directly when the API response doesn't match expectations; MySQL is the source of truth, Redis is a performance layer.
Read test names as business-rule documentation; each test describes a concrete boundary or race condition the system promises to handle.
Turn every production bug into a test that fails before the fix and passes afterward to prevent regressions.
Check request headers—JWT, Idempotency-Key, X-Mock-Payment-Secret—before assuming the request body is wrong.
Never blindly retry on a 409; refresh the resource state or prompt the user instead.
Conclusions

Frontend debugging instincts map surprisingly well to the backend: the Network panel becomes curl, localStorage becomes JWT/Redis, and component state becomes database rows, but the backend adds mandatory layers—transactions, row locks, and cache invalidation—that have no frontend equivalent.

The traceId is an underused superpower; a single header turns a vague "it's broken" report into a precise log query that can pinpoint the exact line of a stack trace.

Many backend bugs that look like code defects are actually configuration or environment mismatches—a profile that disables caching, a test schema that drifted from production, or a Redis instance holding stale JSON that the write path forgot to evict.

Treating tests as executable specifications rather than a chore changes how developers approach debugging: the test name often answers the "what should happen" question faster than reading the implementation.

The five-layer error model (network, protocol, security, business, infrastructure) prevents the common trap of debugging business logic for two hours when the real problem is a missing Content-Type header or an expired JWT.

Concepts & terms
traceId
A unique identifier generated or passed through for each HTTP request, written into both the response and server logs, allowing a single request to be traced across distributed services.
ApiResponse envelope
A unified response wrapper containing a stable business code, a human-readable message, the payload data, a traceId, and a timestamp, used by all APIs in the project so clients can branch on code rather than parsing messages.
Cache Aside pattern
A caching strategy where the application reads from cache first; on a miss it loads from the database, writes to cache, and returns the data. Writes update the database and invalidate the cache to prevent stale data.
Idempotency Key
A client-generated unique key sent in a request header that allows the server to recognize duplicate submissions and return the original result instead of executing the operation twice, critical for payment and order creation.
Conditional UPDATE / optimistic locking
A concurrency control technique where an UPDATE statement includes a version or status condition in the WHERE clause; if another transaction changed the row first, the affected row count is zero and the caller knows to retry or abort.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗