How do you convert an iPhone OSStatus code to something useful?
Solution 1
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 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 2
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 3
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
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
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";
}
}
matt
Updated on July 05, 2022Comments
-
matt almost 2 years
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.
-
DarkDust over 13 yearsThat will result in a nice crash if there is no 0 byte following on the stack soon.
-
coneybeare over 12 yearsThis generates a compiler warning: "Function call argument is an uninitialized value" on the if conditional line
-
tomk almost 12 yearsDon't you think, if the developer who invented OSStatus wanted it to be a string he would declare it as one and not as a signed integer? You cannot or at least sholud not "cast" an integer to a string.
-
kennytm almost 12 years@tomk: (1) Did you realize this piece code comes from the official Apple sample codes? (2) How could you be sure that the developer invented OSStatus does not want to use the 4 bytes as a compact way to store 4 characters? I'm certain this is true, because OSType originates from the Mac OS.
-
tomk almost 12 yearsI have to admit, I only found it afterwards. But as you wrote, "...some OSStatus are four...". "mrep" and "?tmf" really don't sound like proper error codes. See my answer for a public function to convert OSStatus to an error string.
-
kennytm almost 12 years@tomk: That's because you read them backwards. They are
perm
(perm-ission error) andfmt?
(wrong f-or-m-a-t). Does you public method show "permission error" and "wrong format" or just "The operation couldn't be completed."? BTW the method in this answer is public too, just that it's not accomplished in a single line. -
Martin Konicek almost 12 yearsYou would use printf("%d", err).
-
Per Johansson over 11 yearsThe question is old but I'd say this is the correct answer. You can then get a descreptive string, e.g.
2012-11-05 22:28:52.338 foo[7300:707] Error Domain=NSOSStatusErrorDomain Code=-43 "The operation couldn’t be completed. (OSStatus error -43.)" (fnfErr: File not found)
-
fishinear almost 11 yearsYou cannot get anything beyond "The operation couldn't be completed" for many errors this way. A combination of this answer and the accepted one works great.
-
quellish almost 11 yearsUnfortunately, SecCopyErrorMessageString does not exist on iOS.
-
Randall Cook over 10 yearsNot even the presence of Jon Skeet on planet Earth is enough to make this answer right!
-
trojanfoe almost 10 yearsUse a macro and stringify and save even more typing.
-
inorganik almost 9 yearsThis is helpful, though you should add a case for
0
, which means no error. -
Earlz over 8 yearsThis seems to return "unknown error code" for the vast majority of error codes
-
Just a coder over 8 yearsunderstood. i'll leave this up incase its helpful to someone on Mac
-
humblehacker over 8 yearsThis doesn't work on iOS 9 (I haven't tried any other versions) because
[NSBundle bundleWithIdentifier:@"com.apple.security"]
returnsnil
. -
Anton Tropashko about 8 yearsit could not grok -34018
-
Sam almost 8 yearsin swift it does not give anything relevant for code -12792, I've also tried for some other codes but nothing..
-
Sam almost 8 years@kennytm how would that translate into swift? I've been trying to get more details on error code -12792 but did not manage to find more about it..
-
DEADBEEF about 7 yearsWhat's the equivalent of
CreateTypeStringWithOSType
in Swift? I don't manage to use it... -
DEADBEEF almost 7 yearsUnfortunately it doesn't work for all the OSStatus. For exemple it cannot print the error with Core Audio OSStatus
-
MandisaW over 6 yearsThis answer was useful, but the underlying problem of poor error documentation is still an issue. Hitting the OSStatus lookup site did the trick, but this is a lapse on Apple's part.
-
Jules almost 6 years"You cannot convert or "cast" it to a string" ... you are aware that many of Apple's file formats and APIs use "4CC"s, which are sequences of 4 ASCII characters converted to an integer by concatenating them in big-endian order? (4CCs are also used in a variety of media file formats, and have therefore made their way into non-Apple OS media libraries, e.g. Windows DirectShow uses them to identify codecs). Which means that converting them to strings for display purpose is actually a very sensible thing to do with them.
-
Ashley Mills over 5 yearsGreat answer for iOS 11.3 and onwards
-
Darrell Root about 5 yearsThanks for that. Here's the swift syntax: if let error: CFString = SecCopyErrorMessageString(status, nil) {
-
johndoe about 5 yearsIt is included in iOS 11.3 and above.
-
kakyo almost 5 yearsTurns out that this API is not that useful: It simply prints out "OSStatus <the number>" for you, #$%&^*
-
Stanislav Pankevich over 4 yearsThanks for the answer. The code is working but I was missing the errors related to the AVAudioRecorder. I have borrowed your code and added missing errors here: stackoverflow.com/a/58348781/598057. You can add them here as well.
-
KerCodex over 4 yearsI am glad this was useful to you. Everybody should of course adjust the code for errors useful in their context.