flipped-aurora/gin-vue-admin · error

ErrLogFileUnreadable

ErrLogFileUnreadable

Error message

%w: %v

What it means

ReadContent locates the byte range for the requested chunk via findLogChunkStart and reads it with readLogRange; any failure there (seek/read errors, file unreadable) is wrapped with ErrLogFileUnreadable so the API can report the log file content cannot be served.

Source

Thrown at server/service/system/sys_log_viewer.go:184

		return result, err
	}
	if query.Cursor != nil && *query.Cursor < 0 {
		return result, ErrInvalidLogPath
	}

	file, info, err := openValidatedLogFile(query.Date, query.Path)
	if err != nil {
		return result, err
	}
	defer file.Close()

	end := info.Size()
	if query.Cursor != nil && *query.Cursor <= end {
		end = *query.Cursor
	}
	start, limitedByBytes, err := findLogChunkStart(file, end)
	if err != nil {
		return result, fmt.Errorf("%w: %v", ErrLogFileUnreadable, err)
	}

	data, err := readLogRange(file, start, end)
	if err != nil {
		return result, fmt.Errorf("%w: %v", ErrLogFileUnreadable, err)
	}
	if int64(len(data)) < end-start {
		currentInfo, statErr := file.Stat()
		if statErr != nil || currentInfo.Size() < start {
			if statErr != nil {
				return result, fmt.Errorf("%w: %v", ErrLogFileUnreadable, statErr)
			}
			return result, ErrLogFileUnreadable
		}
		info = currentInfo
	}

	result.Content = string(data)

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Ensure the service user can read the specific log file (check file mode, not just directory)
  2. Re-list files and retry — the file may have been rotated away
  3. Check errors.Is(err, ErrLogFileUnreadable) in the handler and surface a 'file unreadable' message
  4. Verify the file still exists at the path returned by ListFiles

Example fix

// before
content, err := svc.ReadContent(ctx, query) // EACCES on file
// after
chmod 640 /var/log/gva/2026-08/app.log
chown gva:gva /var/log/gva/2026-08/app.log
content, err := svc.ReadContent(ctx, query)
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const content = await readContent(query)
} catch (e) {
  if (/unreadable/i.test(e.message)) {
    showError('日志文件无法读取,可能已被轮转')
    await refreshFileList()
  }
}

Prevention

When it happens

Trigger: Calling ReadContent on a log file that cannot be seeked or read — permission denied on the file, file truncated/deleted mid-read, or an underlying I/O error during chunk scanning.

Common situations: Log file rotated (renamed/deleted) between listing and reading; file permissions stricter than directory permissions; log file on flaky storage; reading files owned by another user.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/6cfe4fd3855d0871. Report an issue: GitHub.