diff --git a/XbICalendar/XBICalendar/NSError+XbICError.h b/XbICalendar/XBICalendar/NSError+XbICError.h new file mode 100644 index 0000000..d0e6909 --- /dev/null +++ b/XbICalendar/XBICalendar/NSError+XbICError.h @@ -0,0 +1,18 @@ +// +// NSError+XbICError.h +// XbICalendar +// + +#import + +typedef NS_ENUM(NSUInteger, XbICErrorCode) { + XbICErrorCodeBase = 9000, + XbICErrorCodeBaseICSFileErrors +}; + + +@interface NSError (XbICError) + ++ (NSError*) errorWithCode:(NSUInteger)value message:(NSString*)message; + +@end diff --git a/XbICalendar/XBICalendar/NSError+XbICError.m b/XbICalendar/XBICalendar/NSError+XbICError.m new file mode 100644 index 0000000..fb334fb --- /dev/null +++ b/XbICalendar/XBICalendar/NSError+XbICError.m @@ -0,0 +1,25 @@ +// +// NSError+XbICError.m +// XbICalendar +// +// Created by Andrew Halls on 9/16/15. +// Copyright (c) 2015 GaltSoft. All rights reserved. +// + +#import "NSError+XbICError.h" + +#define XbICalendarErrorDomain @"XbICalendar" + + +@implementation NSError (XbICError) + ++ (NSError*) errorWithCode:(NSUInteger)code message:(NSString*)message { + +return [NSError errorWithDomain: XbICalendarErrorDomain + code:code + userInfo: @{NSLocalizedDescriptionKey: message} + ]; + +} + +@end diff --git a/XbICalendar/XbICalendar.xcodeproj/project.pbxproj b/XbICalendar/XbICalendar.xcodeproj/project.pbxproj index 936792a..552df59 100644 --- a/XbICalendar/XbICalendar.xcodeproj/project.pbxproj +++ b/XbICalendar/XbICalendar.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ 946E26EC1B0F7B9600418534 /* EventKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 946E26EB1B0F7B9600418534 /* EventKit.framework */; }; 946E26EE1B0F7BA500418534 /* EventKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 946E26ED1B0F7BA500418534 /* EventKitUI.framework */; }; 94B0AB131B05A1330057BF2D /* XbICPropertyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 94B0AB121B05A1330057BF2D /* XbICPropertyTest.m */; }; + F10FC2601B85D81600AB6769 /* issue_32.ics in Resources */ = {isa = PBXBuildFile; fileRef = F10FC25F1B85D81600AB6769 /* issue_32.ics */; }; + F10FC2611B85D8CD00AB6769 /* issue_32.ics in Resources */ = {isa = PBXBuildFile; fileRef = F10FC25F1B85D81600AB6769 /* issue_32.ics */; }; F113ED3419863A7B00C37F81 /* 2446.ics in Resources */ = {isa = PBXBuildFile; fileRef = 4DAE352A19720D050097A2D6 /* 2446.ics */; }; F113ED3519863A7F00C37F81 /* calendar.ics in Resources */ = {isa = PBXBuildFile; fileRef = 4DAE3531197370380097A2D6 /* calendar.ics */; }; F113ED3619863A8200C37F81 /* classify.ics in Resources */ = {isa = PBXBuildFile; fileRef = 4DAE3535197379190097A2D6 /* classify.ics */; }; @@ -84,10 +86,12 @@ F12F4E4119346A41003631C5 /* XbICComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = F12F4E4019346A41003631C5 /* XbICComponent.m */; }; F12F4E491935B259003631C5 /* XbICVCalendar.m in Sources */ = {isa = PBXBuildFile; fileRef = F12F4E481935B259003631C5 /* XbICVCalendar.m */; }; F12F4E4D1935CF03003631C5 /* XbICVEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F12F4E4C1935CF03003631C5 /* XbICVEvent.m */; }; + F13D0FB41BA7F73400DD0537 /* XbICalendarIssue32Test.m in Sources */ = {isa = PBXBuildFile; fileRef = F13D0FB31BA7F73400DD0537 /* XbICalendarIssue32Test.m */; }; F148A223194700DD00ED2C6E /* libical.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F148A222194700DD00ED2C6E /* libical.a */; }; F18820261990A41A00177998 /* XbICInvite.m in Sources */ = {isa = PBXBuildFile; fileRef = F18820251990A41A00177998 /* XbICInvite.m */; }; F188202A1990A99A00177998 /* XbICInviteResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F18820291990A99A00177998 /* XbICInviteResponseTests.m */; }; F1DC7727193F208500DB07D4 /* XbICPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = F1DC7726193F208500DB07D4 /* XbICPerson.m */; }; + F1E5B9AA1BA92CDC0057B2AF /* NSError+XbICError.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E5B9A91BA92CDC0057B2AF /* NSError+XbICError.m */; }; F1F5D71419402CEA00D81F71 /* XbICFileTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F1F5D71319402CEA00D81F71 /* XbICFileTableViewController.m */; }; F1F5D71519402E9700D81F71 /* invite.ics in Resources */ = {isa = PBXBuildFile; fileRef = F12F493419346287003631C5 /* invite.ics */; }; F1F5D71619402E9C00D81F71 /* 2445.ics in Resources */ = {isa = PBXBuildFile; fileRef = F12F492A19333E35003631C5 /* 2445.ics */; }; @@ -143,6 +147,7 @@ 946E26EB1B0F7B9600418534 /* EventKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKit.framework; path = System/Library/Frameworks/EventKit.framework; sourceTree = SDKROOT; }; 946E26ED1B0F7BA500418534 /* EventKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKitUI.framework; path = System/Library/Frameworks/EventKitUI.framework; sourceTree = SDKROOT; }; 94B0AB121B05A1330057BF2D /* XbICPropertyTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICPropertyTest.m; sourceTree = ""; }; + F10FC25F1B85D81600AB6769 /* issue_32.ics */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = issue_32.ics; sourceTree = ""; }; F113ED40198643FD00C37F81 /* XbICalendarInviteWriteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICalendarInviteWriteTests.m; sourceTree = ""; }; F117D40619DBA6FC002CD9B5 /* XbICalendar2445Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XbICalendar2445Tests.swift; sourceTree = ""; }; F117D40819DBA7BB002CD9B5 /* XbICalendarTestsBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XbICalendarTestsBridge.h; sourceTree = ""; }; @@ -180,6 +185,7 @@ F12F4E481935B259003631C5 /* XbICVCalendar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICVCalendar.m; sourceTree = ""; }; F12F4E4B1935CF03003631C5 /* XbICVEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XbICVEvent.h; sourceTree = ""; }; F12F4E4C1935CF03003631C5 /* XbICVEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICVEvent.m; sourceTree = ""; }; + F13D0FB31BA7F73400DD0537 /* XbICalendarIssue32Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICalendarIssue32Test.m; sourceTree = ""; }; F148A222194700DD00ED2C6E /* libical.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libical.a; sourceTree = ""; }; F18820241990A41A00177998 /* XbICInvite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XbICInvite.h; sourceTree = ""; }; F18820251990A41A00177998 /* XbICInvite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICInvite.m; sourceTree = ""; }; @@ -187,6 +193,8 @@ F1A240C919C96C6F00139576 /* Bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Bridge.h; sourceTree = ""; }; F1DC7725193F208500DB07D4 /* XbICPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XbICPerson.h; sourceTree = ""; }; F1DC7726193F208500DB07D4 /* XbICPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICPerson.m; sourceTree = ""; }; + F1E5B9A81BA92CDC0057B2AF /* NSError+XbICError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+XbICError.h"; sourceTree = ""; }; + F1E5B9A91BA92CDC0057B2AF /* NSError+XbICError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+XbICError.m"; sourceTree = ""; }; F1F5D71219402CEA00D81F71 /* XbICFileTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XbICFileTableViewController.h; sourceTree = ""; }; F1F5D71319402CEA00D81F71 /* XbICFileTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XbICFileTableViewController.m; sourceTree = ""; }; F1FAB5FE1945B057005D0B35 /* XbICZoneDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XbICZoneDirectory.h; sourceTree = ""; }; @@ -294,6 +302,7 @@ F12F491519332EA5003631C5 /* Supporting Files */, F12F492919333E1A003631C5 /* TestData */, 4DC71134197B4A6A003D4962 /* XbICalendar2445Tests.m */, + F117D40619DBA6FC002CD9B5 /* XbICalendar2445Tests.swift */, 4DAE352F197221770097A2D6 /* XbICalendar2446Tests.m */, 4DAE3533197370580097A2D6 /* XbICalendarCalendarTests.m */, 4DAE3537197379920097A2D6 /* XbICalendarClassifyTests.m */, @@ -303,6 +312,7 @@ F12F491A19332EA5003631C5 /* XbICalendarInMemoryTests.m */, 4DC71132197B3F27003D4962 /* XbICalendarInviteTests.m */, F113ED40198643FD00C37F81 /* XbICalendarInviteWriteTests.m */, + F13D0FB31BA7F73400DD0537 /* XbICalendarIssue32Test.m */, 4DA795261979F1460033A008 /* XbICalendarLargeTests.m */, 4D0767ED197ADF5C0017ED72 /* XbICalendarOverlapTests.m */, 4D0767F1197AE4470017ED72 /* XbICalendarProcessCalendarTests.m */, @@ -313,7 +323,6 @@ 4DC71130197B32FA003D4962 /* XbICalendarStressTestTests.m */, F18820291990A99A00177998 /* XbICInviteResponseTests.m */, 94B0AB121B05A1330057BF2D /* XbICPropertyTest.m */, - F117D40619DBA6FC002CD9B5 /* XbICalendar2445Tests.swift */, ); path = XbICalendarTests; sourceTree = ""; @@ -331,11 +340,15 @@ F12F49241933385D003631C5 /* XbICalendar */ = { isa = PBXGroup; children = ( + F1E5B9A81BA92CDC0057B2AF /* NSError+XbICError.h */, + F1E5B9A91BA92CDC0057B2AF /* NSError+XbICError.m */, F12F492519333899003631C5 /* XbICalendar.h */, F12F4E3F19346A41003631C5 /* XbICComponent.h */, F12F4E4019346A41003631C5 /* XbICComponent.m */, F12F4926193338CB003631C5 /* XbICFile.h */, F12F4927193338CB003631C5 /* XbICFile.m */, + F18820241990A41A00177998 /* XbICInvite.h */, + F18820251990A41A00177998 /* XbICInvite.m */, F1DC7725193F208500DB07D4 /* XbICPerson.h */, F1DC7726193F208500DB07D4 /* XbICPerson.m */, F12F4E4319346AB6003631C5 /* XbICProperty.h */, @@ -346,8 +359,6 @@ F12F4E4C1935CF03003631C5 /* XbICVEvent.m */, F1FAB5FE1945B057005D0B35 /* XbICZoneDirectory.h */, F1FAB5FF1945B057005D0B35 /* XbICZoneDirectory.m */, - F18820241990A41A00177998 /* XbICInvite.h */, - F18820251990A41A00177998 /* XbICInvite.m */, ); name = XbICalendar; path = XBICalendar; @@ -370,6 +381,7 @@ 4DC71126197B32C3003D4962 /* smallcluster.ics */, 4DC71127197B32C3003D4962 /* spanlist.ics */, 4DC71128197B32C3003D4962 /* stresstest.ics */, + F10FC25F1B85D81600AB6769 /* issue_32.ics */, ); path = TestData; sourceTree = ""; @@ -494,6 +506,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F10FC2611B85D8CD00AB6769 /* issue_32.ics in Resources */, F12F4E3C19346826003631C5 /* zoneinfo in Resources */, F113ED3F19863A9D00C37F81 /* stresstest.ics in Resources */, F113ED3619863A8200C37F81 /* classify.ics in Resources */, @@ -535,6 +548,7 @@ F12F491919332EA5003631C5 /* InfoPlist.strings in Resources */, F12F493519346287003631C5 /* invite.ics in Resources */, 4DC7112B197B32C3003D4962 /* stresstest.ics in Resources */, + F10FC2601B85D81600AB6769 /* issue_32.ics in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -551,6 +565,7 @@ F1F5D7171940395A00D81F71 /* XbICProperty.m in Sources */, F12F48FC19332EA4003631C5 /* main.m in Sources */, F1FAB6001945B057005D0B35 /* XbICZoneDirectory.m in Sources */, + F1E5B9AA1BA92CDC0057B2AF /* NSError+XbICError.m in Sources */, F1F5D71419402CEA00D81F71 /* XbICFileTableViewController.m in Sources */, 945795251B0897B200B60E82 /* XbICFileCreateViewController.m in Sources */, 946E26EA1B0F6B5F00418534 /* XbICAddViewController.m in Sources */, @@ -578,6 +593,7 @@ 4D0767F6197AFE5F0017ED72 /* XbICalendarProcessIncomingTests.m in Sources */, F113ED41198643FD00C37F81 /* XbICalendarInviteWriteTests.m in Sources */, F117D40A19DBA7F7002CD9B5 /* XbICFile.m in Sources */, + F13D0FB41BA7F73400DD0537 /* XbICalendarIssue32Test.m in Sources */, 4DAE353C19737D1D0097A2D6 /* XbICalendarIncomingTests.m in Sources */, 4DA795271979F1460033A008 /* XbICalendarLargeTests.m in Sources */, 4DAE352E19721C9C0097A2D6 /* XbICalendarIcsTest.m in Sources */, diff --git a/XbICalendar/XbICalendar/XBICalendar.h b/XbICalendar/XbICalendar/XBICalendar.h index 99aad87..0401968 100644 --- a/XbICalendar/XbICalendar/XBICalendar.h +++ b/XbICalendar/XbICalendar/XBICalendar.h @@ -19,5 +19,3 @@ #import "XbICFile.h" - - diff --git a/XbICalendar/XbICalendar/XbICFile.h b/XbICalendar/XbICalendar/XbICFile.h index 43c4b85..e5874e4 100644 --- a/XbICalendar/XbICalendar/XbICFile.h +++ b/XbICalendar/XbICalendar/XbICFile.h @@ -5,6 +5,7 @@ #import "XbICComponent.h" #import "XbICVCalendar.h" + /** The XbICFile class provides an interface to read and write ICalendar (ICS) files. */ @@ -15,6 +16,11 @@ */ @property (nonatomic, readonly) NSString *path; +/** + Property that stores the NSError value from the previous call + */ +@property (nonatomic, readonly) NSError *error; + /** Initializes an XbICFile instance and sets the filename. @@ -46,6 +52,7 @@ - (BOOL) writeVCalendar: (XbICVCalendar *) vCalendar; + @end diff --git a/XbICalendar/XbICalendar/XbICFile.m b/XbICalendar/XbICalendar/XbICFile.m index 35fb086..7d105bc 100644 --- a/XbICalendar/XbICalendar/XbICFile.m +++ b/XbICalendar/XbICalendar/XbICFile.m @@ -3,11 +3,12 @@ // #import "XbICFile.h" - +#import "NSError+XbICError.h" @interface XbICFile () @property (nonatomic, copy) NSString * pathname; +@property (nonatomic, strong) NSError *error; @property (nonatomic, strong) XbICComponent *icsFileRoot; @@ -21,11 +22,7 @@ - (instancetype)initWithPathname:(NSString *)pathname { self = [super init]; if (self) { self.pathname = pathname; - - - //TODO: Need to check this is configured properly - - } + } return self; @@ -41,20 +38,31 @@ + (instancetype)fileWithPathname:(NSString *)pathname { - (XbICComponent *) read { + NSError * lError; + NSString * caldata = [NSString stringWithContentsOfFile:self.pathname encoding:NSUTF8StringEncoding - error:NULL]; - + error: &lError]; + + self.error = lError; + if (caldata) { - icalcomponent *root = icalparser_parse_string([caldata cStringUsingEncoding:NSUTF8StringEncoding]); + icalcomponent *root = icalparser_parse_string([caldata cStringUsingEncoding: NSUTF8StringEncoding]); if (root) { self.icsFileRoot = [XbICComponent componentWithIcalComponent: root]; + icalrestriction_check(root); + int errors = icalcomponent_count_errors(root); + if (errors) { + self.error = [NSError errorWithCode: XbICErrorCodeBaseICSFileErrors + message: [NSString stringWithFormat:@"Calendar file contains %d erros", errors]]; + } icalcomponent_free(root); } } + return self.icsFileRoot; } @@ -63,9 +71,9 @@ - (BOOL) writeVCalendar: (XbICVCalendar *) vCalendar { NSString * buffer = [vCalendar stringSerializeComponent]; - NSError * error; - if (![buffer writeToFile:self.pathname atomically:YES encoding: NSUTF8StringEncoding error: &error]) { - NSLog(@"Error: %@",error); + NSError * lError; + if (![buffer writeToFile:self.pathname atomically:YES encoding: NSUTF8StringEncoding error: &lError]) { + self.error = lError; return NO; } @@ -85,6 +93,7 @@ - (id)copyWithZone:(NSZone *)zone { if (object) { object.pathname = [self.pathname copyWithZone:zone]; object.icsFileRoot = [self.pathname copyWithZone:zone]; + object.error = [self.error copyWithZone:zone]; } return object; diff --git a/XbICalendar/XbICalendarTests/TestData/issue_32.ics b/XbICalendar/XbICalendarTests/TestData/issue_32.ics new file mode 100644 index 0000000..2ed716c --- /dev/null +++ b/XbICalendar/XbICalendarTests/TestData/issue_32.ics @@ -0,0 +1,21 @@ +BEGIN:VCALENDAR +PRODID:-//ACME/DesktopCalendar//EN +METHOD:REQUEST +VERSION:2.0 +BEGIN:VEVENT +DTSTART:19700308T020000 +DTEND:19970701T190000Z +ORGANIZER:Mailto:A@example.com +ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CUTYPE=INDIVIDUAL:A@example.COM +ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:B@example.fr +ATTENDEE;RSVP=TRUE;CUTYPE=INDIVIDUAL:c@example.jp +DTSTAMP:19970613T190030Z +DTSTART;TZID=America-SanJose:19970701T140000 +DTEND;TZID=America-SanJose:19970701T150000 +RRULE:FREQ=DAILY;INTERVAL=2;WKST=SU +SUMMARY:Dayly Phone Conference +UID:calsrv.example.com-873970198738780@example.com +SEQUENCE:0 +STATUS:CONFIRMED +END:VEVENT +END:VCALENDAR \ No newline at end of file diff --git a/XbICalendar/XbICalendarTests/XbICalendarIcsTest.h b/XbICalendar/XbICalendarTests/XbICalendarIcsTest.h index a6d1759..392ff24 100644 --- a/XbICalendar/XbICalendarTests/XbICalendarIcsTest.h +++ b/XbICalendar/XbICalendarTests/XbICalendarIcsTest.h @@ -29,6 +29,7 @@ @property (nonatomic, strong, readonly) XbICComponent * rootComponent; @property (nonatomic, copy, readonly) NSArray * calendars; @property (nonatomic, copy, readonly) NSArray * events; +@property (nonatomic, strong, readonly) NSError * error; - (XbICComponent *)componentFromIcsFileName:(NSString *)fileName; - (XbICVCalendar *)calendarFromIcsFileName:(NSString *)fileName; diff --git a/XbICalendar/XbICalendarTests/XbICalendarIcsTest.m b/XbICalendar/XbICalendarTests/XbICalendarIcsTest.m index ec14555..68ff0ae 100644 --- a/XbICalendar/XbICalendarTests/XbICalendarIcsTest.m +++ b/XbICalendar/XbICalendarTests/XbICalendarIcsTest.m @@ -16,6 +16,7 @@ @interface XbICalendarIcsTest () @property (nonatomic, strong, readwrite) XbICComponent * rootComponent; @property (nonatomic, copy, readwrite) NSArray * calendars; @property (nonatomic, copy, readwrite) NSArray * events; +@property (nonatomic, strong, readwrite) NSError * error; @end @implementation XbICalendarIcsTest @@ -71,7 +72,11 @@ - (XbICComponent *)componentFromIcsFileName:(NSString *)fileName { NSString *filePath = [self filePathForIcsFileName:fileName]; XbICFile * file = [XbICFile fileWithPathname:filePath]; - return [file read]; + XbICComponent * result = [file read]; + + self.error = file.error; + + return result; } - (XbICVCalendar *)calendarFromIcsFileName:(NSString *)fileName diff --git a/XbICalendar/XbICalendarTests/XbICalendarIssue32Test.m b/XbICalendar/XbICalendarTests/XbICalendarIssue32Test.m new file mode 100644 index 0000000..9dcfb03 --- /dev/null +++ b/XbICalendar/XbICalendarTests/XbICalendarIssue32Test.m @@ -0,0 +1,31 @@ +// +// XbICalendarIssue32Test.m +// XbICalendar +// + +#import + +#import +#import "XbICalendarIcsTest.h" + +@interface XbICalendarIssue32Test : XbICalendarIcsTest +@end + +@implementation XbICalendarIssue32Test + +- (NSString *)icsFileNameUnderTest +{ + return @"issue_32"; +} + +- (void)test_checkforErrors +{ + XCTAssertNotNil(self.rootComponent, @"Initialization"); + XCTAssertEqual([self.calendars count], 1, @"Expected 1 calendars"); + + XCTAssertNotNil(self.error, @"Expect an Error"); + XCTAssertEqual(9001, [[self error] code], @"Expected error code"); +} + + +@end \ No newline at end of file