siyuan-note/siyuan · error

panic(err)

Error message

panic(err)

What it means

The mobile (gomobile) export of kernel.Unzip panics when gulu.Zip.Unzip fails to extract a zip archive. Because gomobile bindings cannot return Go errors conveniently for this void API, failures are surfaced as a panic that the native side must catch. The underlying cause is logged before panicking.

Source

Thrown at kernel/mobile/kernel.go:381

	return filepath.Base(path)
}

func FilterUploadFileName(name string) string {
	return util.FilterUploadFileName(name)
}

func AssetName(name string) string {
	return util.AssetName(name, ast.NewNodeID())
}

func HTML2Markdown(html string) string {
	return util.NewLute().HTML2Md(html)
}

func Unzip(zipFilePath, destination string) {
	if err := gulu.Zip.Unzip(zipFilePath, destination); nil != err {
		logging.LogErrorf("unzip [%s] failed: %s", zipFilePath, err)
		panic(err)
	}
}

// GetExportFilePath 解析导出文件绝对路径,绕过 HTTP 层以避免锁屏密码拦截。
// exportPath 格式为 "/export/xxx.zip" 或 "assets/xxx"。
// 返回文件在磁盘上的绝对路径,以便原生端分块拷贝,避免大文件内存溢出。
// 解析失败返回空字符串。
func GetExportFilePath(exportPath string) (ret string) {
	var absPath string
	if after, ok := strings.CutPrefix(exportPath, "/export/"); ok {
		fileName := after
		if decoded, err := url.PathUnescape(fileName); err == nil {
			fileName = decoded
		}
		fileName = filepath.Clean(fileName)
		if strings.HasPrefix(fileName, "..") {
			logging.LogWarnf("get export file path [%s] blocked: path traversal attempt [%s]", exportPath, fileName)
			return

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Verify the zip file exists and is fully downloaded before calling Unzip
  2. Check/request storage permissions and confirm the destination directory is writable
  3. Catch the panic/exception on the native side and surface a friendly error to the user
  4. Re-download the archive if it is corrupt; verify size or checksum first

Example fix

// before (Java/Kotlin native side)
Unzip(zipPath, dest)
// after
try { Unzip(zipPath, dest) } catch (e: Throwable) { showError("Unzip failed: ${e.message}") }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!fs.existsSync(zipPath) || fs.statSync(zipPath).size === 0) throw new Error('zip missing or empty');

Try / catch

try { Unzip(zipPath, dest) } catch (t) { log(TAG, "Unzip failed", t); showUserError(t); }

Prevention

When it happens

Trigger: Calling Unzip(zipFilePath, destination) from the native (Android/iOS/HarmonyOS) side with a corrupt, missing, or password-protected zip, or a destination path that cannot be written.

Common situations: Interrupted downloads leaving truncated zip files, storage-permission denials on mobile, insufficient disk space, wrong path handling across platform file APIs.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/485ea3644f66723a. Report an issue: GitHub.