Commits

Bill Garrison committed ba722f6

Fixes issue #2, "misuse of NSUnderlyingErrorKey"

Comments (0)

Files changed (4)

NSURL+SOExtendedAttributes.h

 #endif
 #endif
 
+
 /**
  The SOExtendedAttributes category on NSURL enables retrieving and manipulating the extended attributes on a file system item.
  
     SOExtendedAttributesGetValueError,
 };
 
+/** When multiple errors are reported from the xattr API, they are collected and reported under this -[NSError userInfo] dictionary key. */
+extern NSString * const SOUnderlyingErrorsKey;
+
 
 @interface NSURL (SOExtendedAttributes)
 

NSURL+SOExtendedAttributes.m

 
 NSString * const iCloudDoNotBackupAttributeName = @"com.apple.MobileBackup";
 NSString * const SOExtendedAttributesErrorDomain = @"SOExtendedAttributesErrorDomain";
+NSString * const SOUnderlyingErrorsKey = @"SOUnderlyingErrorsKey";
 
 /* Use default options with xattr API that don't resolve symlinks and show the HFS compression extended attribute. */
 
         if (hasErrors && outError)
         {
             NSMutableDictionary *errInfo = [NSMutableDictionary dictionary];
+            [errInfo setObject:NSLocalizedString(@"Failed to get one or more extended attribute values", @"Error message description for SOExtendedAttributesGetValueError") forKey:NSLocalizedDescriptionKey];
             [errInfo setObject:self forKey:NSURLErrorKey];
-            [errInfo setObject:collectedErrors forKey:NSUnderlyingErrorKey];
+            [errInfo setObject:collectedErrors forKey:SOUnderlyingErrorsKey];
             *outError = [NSError errorWithDomain:SOExtendedAttributesErrorDomain code:SOExtendedAttributesGetValueError userInfo:errInfo];
         }
     }
     if (hasErrors && outError)
     {
         NSMutableDictionary *errInfo = [NSMutableDictionary dictionary];
+        [errInfo setObject:NSLocalizedString(@"Failed to set one or more extended attributes.", @"Error message description for SOExtendedAttributesSetValueError.")
+ forKey:NSLocalizedDescriptionKey];
         [errInfo setObject:self forKey:NSURLErrorKey];
-        [errInfo setObject:collectedErrors forKey:NSUnderlyingErrorKey];
+        [errInfo setObject:collectedErrors forKey:SOUnderlyingErrorsKey];
         *outError = [NSError errorWithDomain:SOExtendedAttributesErrorDomain code:SOExtendedAttributesSetValueError userInfo:errInfo];
         return NO;
     }

SOExtendedAttributes.xcodeproj/project.pbxproj

 		F212A55B14CDC65900B65EA9 /* README.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
 		F2191C1614CE06AA004557C9 /* SOUsefulFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOUsefulFunctions.m; sourceTree = SOURCE_ROOT; };
 		F2191C1714CE06AA004557C9 /* SOUsefulFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOUsefulFunctions.h; sourceTree = SOURCE_ROOT; };
+		F26FC50518222B4A00627018 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = SOURCE_ROOT; };
 		F2CBB2B914E8EEE300937A53 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 /* End PBXFileReference section */
 
 		F212A55814CDC65900B65EA9 /* Documentation */ = {
 			isa = PBXGroup;
 			children = (
+				F26FC50518222B4A00627018 /* README.md */,
 				F212A55914CDC65900B65EA9 /* appledoc.sh */,
 				F212A55A14CDC65900B65EA9 /* net.standardorbit.SOExtendedAttributes.docset */,
 				F212A55B14CDC65900B65EA9 /* README.txt */,

UnitTests/SOExtendedAttributes_UnitTests.m

     [super tearDown];
 }
 
+#pragma mark - Error Reporting Tests
+
+- (void) testCollectedErrrors
+{
+    /* Test that underlying errors generated from xattr are collected and reported properly. */
+    
+    NSURL *targetURL = [self generatedTestURL];
+    NSError *error = nil;
+    
+    /* Create a test file */
+    
+    STAssertTrue ([[NSFileManager defaultManager] createFileAtPath:[targetURL path]  contents:[NSData data] attributes:nil], @"Couldn't create test file");
+    
+    NSString *excessivelyLongName1 = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,";
+    NSString *excessivelyLongName2 = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, scooby";
+    NSString *excessivelyLongName3 = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, shaggy";
+
+    NSDictionary *badAttribs = [NSDictionary dictionaryWithObjectsAndKeys:
+                                 @"LexLuthor" ,excessivelyLongName1,
+                                @"Magneto", excessivelyLongName2,
+                                @"KhanNoonianSingh", excessivelyLongName3,
+                                nil
+                                ];
+    
+    BOOL didAdd = [targetURL setExtendedAttributes:badAttribs error:&error];
+    
+    NSLog (@"error: %@", error);
+    
+    STAssertFalse (didAdd, @"Expected failure");
+    
+    STAssertNotNil (error, @"Expected an error report");
+    STAssertTrue ( [[[error userInfo] objectForKey:SOUnderlyingErrorsKey] isKindOfClass:[NSArray class]], @"Expected array of collected errors.");
+    STAssertTrue ( [[[error userInfo] objectForKey:SOUnderlyingErrorsKey] count] > 0, @"Expected multiple errors to be collected into an array.");
+}
 
 #pragma mark
 #pragma mark Batch Attribute Tests
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.