fix: validate cache data and suppress static file logging

This commit is contained in:
2026-04-22 20:39:47 +02:00
parent bfb50aa76e
commit c860a1a70a
4 changed files with 45 additions and 5 deletions

View File

@@ -41,12 +41,15 @@ RUN apt-get update && apt-get install -y ca-certificates sqlite3 && rm -rf /var/
RUN mkdir -p /app/data
COPY --from=builder /app/main_server .
COPY --from=builder /app/entrypoint.sh .
COPY --from=builder /app/static ./static
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/migrations ./migrations
RUN chmod +x ./entrypoint.sh
# Expose the application port
EXPOSE 3000
# Run entrypoint which handles migrations
CMD ["./main_server"]
# Run entrypoint which handles migrations and cache clearing
ENTRYPOINT ["./entrypoint.sh"]

11
entrypoint.sh Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -e
# Clear potentially corrupted Jikan cache entries on each deploy
DB_FILE="${DATABASE_FILE:-/app/data/mal.db}"
if [ -f "$DB_FILE" ]; then
sqlite3 "$DB_FILE" "DELETE FROM jikan_cache WHERE key LIKE 'top:%';" 2>/dev/null || true
fi
# Start the server
exec ./main_server

View File

@@ -232,10 +232,27 @@ type cacheResult struct {
hasStale bool
}
func isEmptyResult(out any) bool {
switch v := out.(type) {
case *TopAnimeResponse:
return len(v.Data) == 0
case *SearchResponse:
return len(v.Data) == 0
case *AnimeResponse:
return v.Data.MalID == 0
case *EpisodesResponse:
return len(v.Data) == 0
}
return false
}
func (c *Client) getWithCache(ctx context.Context, cacheKey string, ttl time.Duration, url string, out any) error {
if c.getCache(ctx, cacheKey, out) {
if !isEmptyResult(out) {
return nil
}
log.Printf("jikan: cache hit for %s but data is empty, refetching", cacheKey)
}
var stale any
hasStale := c.getStaleCache(ctx, cacheKey, &stale)
@@ -245,11 +262,11 @@ func (c *Client) getWithCache(ctx context.Context, cacheKey string, ttl time.Dur
staleBytes, marshalErr := json.Marshal(stale)
if marshalErr == nil {
unmarshalErr := json.Unmarshal(staleBytes, out)
if unmarshalErr == nil {
if unmarshalErr == nil && !isEmptyResult(out) {
return nil
}
}
log.Printf("jikan: stale cache unmarshal failed, falling back to error: %v", err)
log.Printf("jikan: stale cache unmarshal failed or empty, falling back to error: %v", err)
}
return err
}

View File

@@ -6,6 +6,7 @@ import (
"log"
"net"
"net/http"
"strings"
"time"
)
@@ -67,6 +68,14 @@ func (rw *statusRecorder) Unwrap() http.ResponseWriter {
func RequestLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
if strings.HasPrefix(r.URL.Path, "/dist/static/") ||
strings.HasPrefix(r.URL.Path, "/static/") ||
r.URL.Path == "/favicon.ico" {
next.ServeHTTP(w, r)
return
}
recorder := newStatusRecorder(w)
next.ServeHTTP(recorder, r)