WeTransfer / Diagnostics

Allow users to easily share Diagnostics with your support team to improve the flow of fixing bugs.
MIT License
933 stars 53 forks source link

Change MXCrashDiganostic Loggable to use the named exception_type exception_code and signal where possible #149

Closed edorphy closed 10 months ago

edorphy commented 1 year ago

@AvdLee I think that the MXCrashDiagnostic's loggable representation would be much more meaningful if the exception type, code, and signal were converted from their integer form to human readable type.

This is how Apple represents them in crash files so it would align with system design and system generated crash reports.

References: https://developer.apple.com/documentation/xcode/examining-the-fields-in-a-crash-report#Exception-information https://developer.apple.com/documentation/xcode/understanding-the-exception-types-in-a-crash-report

I plan to do this in my fork and would be happy to contribute a PR for this if you feel it fits the intent of the metric kit loggable representations.

@available(iOS 14.0, *)
extension MXCrashDiagnostic {
    var logDescription: String {
        return """
        💥  Reason: \(terminationReason ?? "")
            Type: \(exceptionType: exceptionType?.int32Value)
            Code: \(exceptionCode: exceptionCode?.int32Value)
            Signal: \(signal: signal?.int32Value)
            OS: \(metaData.osVersion)
            Build: \(metaData.applicationBuildVersion)

        \(callStackTree.logDescription)
        """
    }
}

Technically we know that the int32Value's will not be nil from the documentation, but they're an NSNumber so doing some 'guarantee' nil checking is necessary for robustness.

extension String.StringInterpolation {
    mutating func appendInterpolation(signal: Int32?) {
        guard let signal else {
            appendLiteral("")
            return
        }

        let literal: String

        switch signal {
        case SIGKILL:
            literal = "SIGKILL"

        case SIGTERM:
            literal = "SIGTERM"

        default:
            // TODO: All other signals defined in usr/include/sys/signal.h
            literal = "\(signal)"
        }

        self.appendLiteral(literal)
    }

    mutating func appendInterpolation(exceptionType: Int32?) {
        guard let exceptionType else {
            appendLiteral("")
            return
        }

        let literal: String

        switch exceptionType {
        case EXC_BAD_ACCESS:
            literal = "EXC_BAD_ACCESS"

        case EXC_BAD_INSTRUCTION:
            literal = "EXC_BAD_INSTRUCTION"

        default:
            // TODO: All other exception types defined in usr/include/mach/exception_types.h
            literal = "\(exceptionType)"
        }

        appendLiteral(literal)
    }

    mutating func appendInterpolation(exceptionCode: Int32?) {
        // TODO: Implement detection of code per exception type referencing usr/include/mach/exception_types.h
    }
}
AvdLee commented 1 year ago

@edorphy this all makes total sense, I would love to review a PR for that!

github-actions[bot] commented 11 months ago

This issue is stale because it has been open for 30 days with no activity. Remove the Stale label or comment or this will be closed in 10 days.