How do you convert an iPhone OSStatus code to something useful?

IosMacosCocoa TouchCocoaError Handling

Ios Problem Overview


I am getting more than a little sick of this iPhone SDK and its documentation...

I am calling AudioConverterNew

in the documentation under Returns: it says "returns a status code" ... really...

so far, through playing around with the parameters I have only been able to get two different errors neither of which are listed at the bottom of the Audio Converter reference.

they are 'mrep' and '?tmf' (casting the OSStatus to a char array) but the specific codes aren't really the point.

as far as I can tell, random error codes are defined in random files, so you can't just search one file, I can't find a help document that just lets you search for an error code to get more info, and from what I can tell, in OS X you can use GetMacOSStatusErrorString() to convert an error to something useful, but there is no iPhone equivalent?

any help would be greatly appreciated.

EDIT:

ok, so casting them gives them in reverse (something I checked for 'mrep' but was not there either way round) , fmt? is in the list for the Audio Converter api, and is pretty self explanatory if a bit vague, but fair enough, still 'perm' isn't there (although it might be something to do with the simulator not supporting aac decoding) and my general question still stands.

Ios Solutions


Solution 1 - Ios

OSStatus is a signed integer value. You cannot convert or "cast" it to a string. You can convert it to a NSError like this:

NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];

Solution 2 - Ios

No. Not completely.

Some OSStatus are four-character-codes, so you can use (extracted from iPhone SDK's sample code "CAXException.h")

static char *FormatError(char *str, OSStatus error)
{
    // see if it appears to be a 4-char-code
    *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error);
    if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
        str[0] = str[5] = '\'';
        str[6] = '\0';
    } else {
        // no, format it as an integer
        sprintf(str, "%d", (int)error);
    }
    return str;
}

(See https://stackoverflow.com/questions/14222435/ios-c-convert-integer-into-four-character-string for some more ways to convert fourcc into string, including Swift)

NSError's NSOSStatusErrorDomain is able to decode some OS errors. See @tomk's answer.

If you don't need to decode the number in program for the user, you may use the macerror script to manually find out the meaning, as mentioned in @lros's answer. The list of OSStatus supported can be found from its source code in /System/Library/Perl/Extras/5.18/Mac/Errors.pm.

There is also an online service http://osstatus.com/ collecting errors from all public frameworks. They are still not really complete e.g. the mapping to -12792 mentioned in the comment is missing. Probably it is a code from a private framework.

Solution 3 - Ios

This is available on macOS and for iOS from 11.3 and above.

I know this is an old post, but I was reading the apple docs in a section related to keychains. They mention a method that is used to convert OSStatus errors into something readable.

> SecCopyErrorMessageString > > Returns a string explaining the meaning of a security result code. > > SecCopyErrorMessageString (OSStatus status, void* reserved );

Useage:

NSString* ErrMsg = (__bridge_transfer NSString *) SecCopyErrorMessageString(theOSStatusError, NULL);

It worked for me with my keychain OSStatus errors. Does it work for you? You will need Security.Framework added to your project to use this method.

Solution 4 - Ios

I recently ran across another approach: the macerror command. Print out the OSStatus value as a signed integer. Then in a terminal window (on your Mac, not your iDevice!) type for example macerror -50. It will respond with a brief description. Obviously this is only helpful for you, during development.

Solution 5 - Ios

Here is the code I wrote, hope it save you some typing... er, don't know how to make it show up correctly.

- (NSString *)OSStatusToStr:(OSStatus)st
{
    switch (st) {
        case kAudioFileUnspecifiedError:
            return @"kAudioFileUnspecifiedError";
            
        case kAudioFileUnsupportedFileTypeError:
            return @"kAudioFileUnsupportedFileTypeError";
            
        case kAudioFileUnsupportedDataFormatError:
            return @"kAudioFileUnsupportedDataFormatError";
            
        case kAudioFileUnsupportedPropertyError:
            return @"kAudioFileUnsupportedPropertyError";
            
        case kAudioFileBadPropertySizeError:
            return @"kAudioFileBadPropertySizeError";
            
        case kAudioFilePermissionsError:
            return @"kAudioFilePermissionsError";
            
        case kAudioFileNotOptimizedError:
            return @"kAudioFileNotOptimizedError";
            
        case kAudioFileInvalidChunkError:
            return @"kAudioFileInvalidChunkError";
            
        case kAudioFileDoesNotAllow64BitDataSizeError:
            return @"kAudioFileDoesNotAllow64BitDataSizeError";
            
        case kAudioFileInvalidPacketOffsetError:
            return @"kAudioFileInvalidPacketOffsetError";
            
        case kAudioFileInvalidFileError:
            return @"kAudioFileInvalidFileError";
            
        case kAudioFileOperationNotSupportedError:
            return @"kAudioFileOperationNotSupportedError";
            
        case kAudioFileNotOpenError:
            return @"kAudioFileNotOpenError";
            
        case kAudioFileEndOfFileError:
            return @"kAudioFileEndOfFileError";
            
        case kAudioFilePositionError:
            return @"kAudioFilePositionError";
            
        case kAudioFileFileNotFoundError:
            return @"kAudioFileFileNotFoundError";
            
        default:
            return @"unknown error";
    }
}

Solution 6 - Ios

I recently found this really nice website that's worked for every status value I've thrown at it. It's a lot more user friendly than grepping through the framework header files: http://www.osstatus.com/

Solution 7 - Ios

I combined a few answers. Actually I were looking something like „throw errorForStatusCode(status)”. But in the end achieved:

    guard status == errSecSuccess else {
        throw  NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: SecCopyErrorMessageString(status, nil) ?? "Undefined error"])
    }

SecCopyErrorMessageString is available from iOS 11.3 https://developer.apple.com/documentation/security/1542001-security_framework_result_codes

Solution 8 - Ios

For iOS 11.3+, I'm using an extension on OSStatus

extension OSStatus {
    
    var error: NSError? {
        guard self != errSecSuccess else { return nil }
        
        let message = SecCopyErrorMessageString(self, nil) as String? ?? "Unknown error"
        
        return NSError(domain: NSOSStatusErrorDomain, code: Int(self), userInfo: [
            NSLocalizedDescriptionKey: message])
    }
}

which you can call like…

let status = SecItemAdd(attributes as CFDictionary, nil)
    
if let error = status.error {
    throw error
}    
// etc

Having written this I noticed this is very close to @RomanMykitchak's earlier answer (so please give him the upvote) - but I'll leave it here as the extension might prove useful to someone.

Solution 9 - Ios

I created an OSStatus extension that you may find useful. It logs a full error message for audio related errors, otherwise when possible the four-character-code, otherwise the OSStatus number that you could look-up in https://www.osstatus.com

It furthers adds useful information like the file, the function and the line where the error occurred.

Here is the code:

let isDebug = true

//**************************
// OSStatus extensions for logging
//**************************
extension OSStatus {
    //**************************
    func asString() -> String? {
        let n = UInt32(bitPattern: self.littleEndian)
        guard let n1 = UnicodeScalar((n >> 24) & 255), n1.isASCII else { return nil }
        guard let n2 = UnicodeScalar((n >> 16) & 255), n2.isASCII else { return nil }
        guard let n3 = UnicodeScalar((n >>  8) & 255), n3.isASCII else { return nil }
        guard let n4 = UnicodeScalar( n        & 255), n4.isASCII else { return nil }
        return String(n1) + String(n2) + String(n3) + String(n4)
    } // asString
    
    //**************************
    func detailedErrorMessage() -> String? {
        switch(self) {
        //***** AUGraph errors
        case kAUGraphErr_NodeNotFound:             return "AUGraph Node Not Found"
        case kAUGraphErr_InvalidConnection:        return "AUGraph Invalid Connection"
        case kAUGraphErr_OutputNodeErr:            return "AUGraph Output Node Error"
        case kAUGraphErr_CannotDoInCurrentContext: return "AUGraph Cannot Do In Current Context"
        case kAUGraphErr_InvalidAudioUnit:         return "AUGraph Invalid Audio Unit"
            
        //***** MIDI errors
        case kMIDIInvalidClient:     return "MIDI Invalid Client"
        case kMIDIInvalidPort:       return "MIDI Invalid Port"
        case kMIDIWrongEndpointType: return "MIDI Wrong Endpoint Type"
        case kMIDINoConnection:      return "MIDI No Connection"
        case kMIDIUnknownEndpoint:   return "MIDI Unknown Endpoint"
        case kMIDIUnknownProperty:   return "MIDI Unknown Property"
        case kMIDIWrongPropertyType: return "MIDI Wrong Property Type"
        case kMIDINoCurrentSetup:    return "MIDI No Current Setup"
        case kMIDIMessageSendErr:    return "MIDI Message Send Error"
        case kMIDIServerStartErr:    return "MIDI Server Start Error"
        case kMIDISetupFormatErr:    return "MIDI Setup Format Error"
        case kMIDIWrongThread:       return "MIDI Wrong Thread"
        case kMIDIObjectNotFound:    return "MIDI Object Not Found"
        case kMIDIIDNotUnique:       return "MIDI ID Not Unique"
        case kMIDINotPermitted:      return "MIDI Not Permitted"
            
        //***** AudioToolbox errors
        case kAudioToolboxErr_CannotDoInCurrentContext: return "AudioToolbox Cannot Do In Current Context"
        case kAudioToolboxErr_EndOfTrack:               return "AudioToolbox End Of Track"
        case kAudioToolboxErr_IllegalTrackDestination:  return "AudioToolbox Illegal Track Destination"
        case kAudioToolboxErr_InvalidEventType:         return "AudioToolbox Invalid Event Type"
        case kAudioToolboxErr_InvalidPlayerState:       return "AudioToolbox Invalid Player State"
        case kAudioToolboxErr_InvalidSequenceType:      return "AudioToolbox Invalid Sequence Type"
        case kAudioToolboxErr_NoSequence:               return "AudioToolbox No Sequence"
        case kAudioToolboxErr_StartOfTrack:             return "AudioToolbox Start Of Track"
        case kAudioToolboxErr_TrackIndexError:          return "AudioToolbox Track Index Error"
        case kAudioToolboxErr_TrackNotFound:            return "AudioToolbox Track Not Found"
        case kAudioToolboxError_NoTrackDestination:     return "AudioToolbox No Track Destination"
            
        //***** AudioUnit errors
        case kAudioUnitErr_CannotDoInCurrentContext: return "AudioUnit Cannot Do In Current Context"
        case kAudioUnitErr_FailedInitialization:     return "AudioUnit Failed Initialization"
        case kAudioUnitErr_FileNotSpecified:         return "AudioUnit File Not Specified"
        case kAudioUnitErr_FormatNotSupported:       return "AudioUnit Format Not Supported"
        case kAudioUnitErr_IllegalInstrument:        return "AudioUnit Illegal Instrument"
        case kAudioUnitErr_Initialized:              return "AudioUnit Initialized"
        case kAudioUnitErr_InvalidElement:           return "AudioUnit Invalid Element"
        case kAudioUnitErr_InvalidFile:              return "AudioUnit Invalid File"
        case kAudioUnitErr_InvalidOfflineRender:     return "AudioUnit Invalid Offline Render"
        case kAudioUnitErr_InvalidParameter:         return "AudioUnit Invalid Parameter"
        case kAudioUnitErr_InvalidProperty:          return "AudioUnit Invalid Property"
        case kAudioUnitErr_InvalidPropertyValue:     return "AudioUnit Invalid Property Value"
        case kAudioUnitErr_InvalidScope:             return "AudioUnit InvalidScope"
        case kAudioUnitErr_InstrumentTypeNotFound:   return "AudioUnit Instrument Type Not Found"
        case kAudioUnitErr_NoConnection:             return "AudioUnit No Connection"
        case kAudioUnitErr_PropertyNotInUse:         return "AudioUnit Property Not In Use"
        case kAudioUnitErr_PropertyNotWritable:      return "AudioUnit Property Not Writable"
        case kAudioUnitErr_TooManyFramesToProcess:   return "AudioUnit Too Many Frames To Process"
        case kAudioUnitErr_Unauthorized:             return "AudioUnit Unauthorized"
        case kAudioUnitErr_Uninitialized:            return "AudioUnit Uninitialized"
        case kAudioUnitErr_UnknownFileType:          return "AudioUnit Unknown File Type"
        case kAudioUnitErr_RenderTimeout:             return "AudioUnit Rendre Timeout"
            
        //***** AudioComponent errors
        case kAudioComponentErr_DuplicateDescription:   return "AudioComponent Duplicate Description"
        case kAudioComponentErr_InitializationTimedOut: return "AudioComponent Initialization Timed Out"
        case kAudioComponentErr_InstanceInvalidated:    return "AudioComponent Instance Invalidated"
        case kAudioComponentErr_InvalidFormat:          return "AudioComponent Invalid Format"
        case kAudioComponentErr_NotPermitted:           return "AudioComponent Not Permitted "
        case kAudioComponentErr_TooManyInstances:       return "AudioComponent Too Many Instances"
        case kAudioComponentErr_UnsupportedType:        return "AudioComponent Unsupported Type"
            
        //***** Audio errors
        case kAudio_BadFilePathError:      return "Audio Bad File Path Error"
        case kAudio_FileNotFoundError:     return "Audio File Not Found Error"
        case kAudio_FilePermissionError:   return "Audio File Permission Error"
        case kAudio_MemFullError:          return "Audio Mem Full Error"
        case kAudio_ParamError:            return "Audio Param Error"
        case kAudio_TooManyFilesOpenError: return "Audio Too Many Files Open Error"
        case kAudio_UnimplementedError:    return "Audio Unimplemented Error"

        default: return nil
        } // switch(self)
    } // detailedErrorMessage

    //**************************
    func debugLog(filePath: String = #file, line: Int = #line, funcName: String = #function) {
        guard isDebug, self != noErr else { return }
        let fileComponents = filePath.components(separatedBy: "/")
        let fileName = fileComponents.last ?? "???"
        
        var logString = "OSStatus = \(self) in \(fileName) - \(funcName), line \(line)"
        
        if let errorMessage = self.detailedErrorMessage() { logString = errorMessage + ", " + logString }
        else if let errorCode = self.asString()           { logString = errorCode    + ", " + logString }
        
        NSLog(logString)
    } // debugLog
} // extension OSStatus

And usage would be:

//***** Create audioGraph
NewAUGraph(&audioGraph).debugLog()

//***** Testing .debugLog() OSStatus extension
kAUGraphErr_InvalidAudioUnit.debugLog()
OSStatus(560226676).debugLog()
OSStatus(-125).debugLog()

The resulting logs for the three tests:

2018-11-12 19:41:48.427606+0100 HexaSynth[5875:102611] AUGraph Invalid Audio Unit, OSStatus = -10864 in SoftSynthesizer.swift - init(soundFontFileName:), line 40

2018-11-12 19:41:48.428403+0100 HexaSynth[5875:102611] !dat, OSStatus = 560226676 in SoftSynthesizer.swift - init(soundFontFileName:), line 41

2018-11-12 19:41:48.428638+0100 HexaSynth[5875:102611] OSStatus = -125 in SoftSynthesizer.swift - init(soundFontFileName:), line 42

Solution 10 - Ios

Use the OSX calc program. Select "programmer" mode in presentation menu. Then type your code in decimal représentation. Then choose the "ascii" button and the calc will show you the 4 char translation such as "!init", "!cat", etc...

Solution 11 - Ios

Failing a description string, it's convenient to convert OSStatus values to strings that look like their four-character definitions. At least then you can grep headers in hopes of finding a comment about what the status means.

// declaration:  extern CFStringRef CreateTypeStringWithOSType(OSType inType);

OSStatus result = ...;

if (result != noErr) {
    NSString *statusString = (NSString *)CreateTypeStringWithOSType(result);
    NSLog(@"Error while $VERBing: %@", statusString);
    [statusString release]; // because "Create..."
    statusString = nil;
}

Solution 12 - Ios

Most time maybe you just need to find the error code in the .h files

I just made a python script to find the code (when you debug/print a osstatus code)

https://github.com/sprhawk/MyGist/blob/master/tools/find_osstatus_error.py

Solution 13 - Ios

If you want to create a command line utility, for use during development and support, then you can still use the deprecated Carbon methods, even in 10.9 (Mavericks). You obviously can't use this in an app you are submitting to Apple for inclusion in the App Stores.

#import <Foundation/Foundation.h>
#import <CoreServices/CoreServices.h>
 
int main(int argc, const char **argv)
{
    @autoreleasepool {
        for (int i = 1; i < argc; i++) {
            char *endp;
            long value = strtol(argv[i], &endp, 10);
            if (*endp == '\0') {
                printf("%10ld: %s (%s)\n",
                    value,
                    GetMacOSStatusCommentString((OSStatus)value),
                    GetMacOSStatusErrorString((OSStatus)value));
            } else {
                fprintf(stderr, "Invalid OSStatus code '%s' ignored\n", argv[i]);
            }
        }
    }
}

Compile with:

$ clang -fobjc-arc -o osstatus osstatus.m -framework Foundation -framework CoreServices

copy it somewhere in your $PATH:

$ cp osstatus ~/bin

and feed it error codes from your log files or error reports:

$ osstatus -47
   -47: File is busy (delete) (fBsyErr)

Solution 14 - Ios

This is not a direct answer to OP's question, but I think it will be useful to whoever is concerned with these OSStatus return codes:

Search for keyword "Result Codes" in Xcode documentation (Organizer) and we get a more or less categorized return codes documentation sections in the "System Guides" result.

If you just need to use some codes directly in your custom functions, they are very helpful.

Solution 15 - Ios

OSStatus errors can be bytes representing a 4-char code, or any number of errors defined in MacErrors.h.

If an OSStatus error is 0 or noErr that means you have no error.

Or, try looking up your error number in MacErrors.h:

http://www.opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/MacErrors.h

Solution 16 - Ios

This might be help.

static NSString *stringForOSStatus(OSStatus status)
{
    NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.apple.security"];
    NSString *key = [NSString stringWithFormat:@"%d", status];
    return [bundle localizedStringForKey:key value:key table:@"SecErrorMessages"];
}

Solution 17 - Ios

for Security framework on IOS given that SecCopyErrorMessageString is missing on the platform it's DYI

add error codes at the bottom of

https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices

to your very own switch.

for example

		let status : OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
		switch status {
		case errSecSuccess:
			return nil
		case errSecAuthFailed:
            // that's the result of dumping kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly into the query
			return "changing app lock type on a device without fingerprint and/or passcode setup is not allowed".localized
		default:
            return "unhandled case: implement this"
		}

Solution 18 - Ios

This is what you need https://www.osstatus.com/. Just search for given OSStatus.

Solution 19 - Ios

OSStatus err; ... printf("%s", (char*)&err);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmattView Question on Stackoverflow
Solution 1 - IostomkView Answer on Stackoverflow
Solution 2 - IoskennytmView Answer on Stackoverflow
Solution 3 - IosJust a coderView Answer on Stackoverflow
Solution 4 - IoslrosView Answer on Stackoverflow
Solution 5 - IosEcho LuView Answer on Stackoverflow
Solution 6 - IosEarlzView Answer on Stackoverflow
Solution 7 - IosRoman MykitchakView Answer on Stackoverflow
Solution 8 - IosAshley MillsView Answer on Stackoverflow
Solution 9 - IosKerCodexView Answer on Stackoverflow
Solution 10 - IosAlbrecht AndrzejewskiView Answer on Stackoverflow
Solution 11 - IosShonView Answer on Stackoverflow
Solution 12 - IossprhawkView Answer on Stackoverflow
Solution 13 - IostrojanfoeView Answer on Stackoverflow
Solution 14 - IoskakyoView Answer on Stackoverflow
Solution 15 - IosinorganikView Answer on Stackoverflow
Solution 16 - IosMimuView Answer on Stackoverflow
Solution 17 - IosAnton TropashkoView Answer on Stackoverflow
Solution 18 - IosBoris NikolicView Answer on Stackoverflow
Solution 19 - IospeterView Answer on Stackoverflow