Result values. These are handled by the following mechanism rather than one value at a time. The following example shows how to handle all errors belonging to the NotFound category.
if(result <= nn::fs::ResultNotFound())
{
// This can catch nn::fs::ResultMediaNotFound as well.
}
The Result objects returned by FS functions are forbidden from using the arithmetic operators == or !=. Using these causes a build error. Also note that the following two examples are equivalent.
if(nn::fs::ResultNotFound::Includes(result))
{
...
}
if(nn::fs::ResultNotFound() >= result)
{
...
}
Do not directly handle any Result values that are not mentioned in the Function Reference Manual.
Result values indicate errors that are caused by application bugs and other such problems. You must fix your program so that these do not occur in retail products.
The Result values listed above may be caused by user operations or it may be impossible to get rid of them entirely during development. You must handle errors that can be caused by the user. Some functions may also specify errors that must not occur in retail products, even though the corresponding Result values are not among those listed above. For more information, see the documentation for each of these functions in the Function Reference Manual.
Try functions (which have the prefix Try added to the function name), and non-Try functions (which do not contain this prefix). Try functions return a Result as the return value, unless an fatal internal error occurs. Instead of returning Results, non-Try functions are implemented to display an error screen whenever an internal error returns, regardless of whether the error is fatal. Control does not return from the function in this case.Try functions. (During development, make sure to eliminate situations in which an error could occur because of an attempt to open a nonexistent file.)Try functions should always be used for error handling. Do not use non-Try functions because they can easily jump to error screens as a result of user operations.
// Control internally jumps to the error display screen when an error occurs.
// The application does not need to handle errors.
// NOTE: When developing an application, confirm that you are passing enough working memory as an argument.
// Also check your Omakefile and RSF file to determine whether a ROMFS is created at build time.
nn::fs::MountRom();
nn::Result result = nn::fs::MountSaveData();
if(result.IsFailure())
{
if(result <= nn::fs::ResultNotFormatted())
{
// Formatting required.
// CAUSE: Unformatted save data region.
// NOTE: You must always format a save data region before mounting it for the first time.
result = nn::fs::FormatSaveData();
}
else if(result <= nn::fs::ResultBadFormat())
{
// Formatting required.
// CAUSE: Invalid file format.
result = nn::fs::FormatSaveData();
}
else if(result <= nn::fs::ResultVerificationFailed())
{
// Formatting required.
// CAUSE: Corrupted or tampered-with save data.
// NOTE: This state is never the result of user operations when there is automatic redundancy.
// This error may be caused by user operations (such as removing a card or turning off the system while data is being written) when there is no automatic redundancy.
result = nn::fs::FormatSaveData();
}
else if(result <= nn::fs::ResultOperationDenied())
{
// This error generally does not occur so no handling is required.
// NOTE: But nn::fs::ResultMediaAccessError is returned if failure is due to a bad connection or other hardware factor.
// In such cases, recovery may be possible by retrying, re-inserting the Game Card, restarting the system, or some other action.
}
else
{
// Unexpected error if other than the above
NN_ERR_THROW_FATAL_ALL(result);
}
// Troubleshooting after formatting
if(result.IsFailure())
{
// Here, the act of formatting save data never fails.
// NOTE: When developing your application, confirm that the maxFiles and maxDirectories arguments are not too big.
// Also confirm that the content of the RSF file is correct.
NN_ERR_THROW_FATAL_ALL(result);
}
else
{
// Remount
result = nn::fs::MountSaveData();
if(result.IsFailure())
{
// The same as when making the first call.
// (Supplement) A mount operation never fails immediately after data has been successfully formatted.
}
}
}
nn::Result result = nn::fs::MountExtSaveData();
if(result.IsFailure())
{
if(result <= nn::fs::ResultNotFound())
{
if(result <= nn::fs::ResultMediaNotFound())
{
// An SD Card has not been inserted.
// Note: This error is also returned if the SD Card is damaged or if some medium other than an SD Card is inserted.
// In such cases, an insertion event registered by RegisterSdmcInsertedEvent is signaled.
}
else
{
// The specified expanded save data does not exist and must be created.
// NOTE: Confirm that the ID you specified is correct when developing your application.
result = nn::fs::CreateExtSaveData();
}
}
else if(result <= nn::fs::ResultNotFormatted())
{
// You must recreate the expanded save data.
// CAUSE: Failed to create expanded save data.
result = nn::fs::DeleteExtSaveData();
if(result.IsSuccess())
{
result = nn::fs::CreateExtSaveData();
}
}
else if(result <= nn::fs::ResultBadFormat())
{
// You must format the SD Card.
}
else if(result <= nn::fs::ResultVerificationFailed())
{
// You must recreate the expanded save data.
// CAUSE: Corrupted or tampered-with save data.
result = nn::fs::DeleteExtSaveData();
if(result.IsSuccess())
{
result = nn::fs::CreateExtSaveData();
}
}
else if(result <= nn::fs::ResultOperationDenied())
{
if(result <= nn::fs::ResultWriteProtected())
{
// The SD Card is write-protected.
// NOTE: This occurs if the data recovery sequence is run during a mount operation.
}
else if(result <= nn::fs::ResultMediaAccessError())
{
// This error is only returned when the cause is hardware-related, such as a loose connection.
// In such cases, recovery may be possible by retrying, re-inserting the Game Card, restarting the system, or some other action.
}
else
{
// The file or directory on the SD card may be read-only.
// NOTE: This occurs if the data recovery sequence is run during a mount operation.
}
}
else
{
// Unexpected error if other than the above
NN_ERR_THROW_FATAL_ALL(result);
}
// Troubleshooting after data has been created
if(result.IsFailure())
{
if(result <= nn::fs::ResultNotEnoughSpace())
{
// The SD Card does not have the necessary free space.
}
else if(result <= nn::fs::ResultNotFormatted())
{
// An error has occurred, interrupting the process of data creation.
}
else if(result <= nn::fs::ResultOperationDenied())
{
if(result <= nn::fs::ResultWriteProtected())
{
// The SD Card is write-protected.
}
else if(result <= nn::fs::ResultMediaAccessError())
{
// This error is only returned when the cause is hardware-related, such as a loose connection.
// In such cases, recovery may be possible by retrying, re-inserting the Game Card, restarting the system, or some other action.
}
else
{
// The directory on the SD card may be read-only.
// NOTE: This occurs if the data recovery sequence is run during a mount operation.
}
}
else
{
// Unexpected error if other than the above
// NOTE: When developing your application, confirm that valid values are passed to iconData and iconDataSize.
NN_ERR_THROW_FATAL_ALL(result);
}
}
else
{
// Remount
result = nn::fs::MountExtSaveData();
if(result.IsFailure())
{
// The same as when making the first call.
// (Supplement) As long as the SD Card is not removed, mount operations carried out immediately after the data is created will never fail.
}
}
}
Try functions (which have the prefix Try added to the function name), and non-Try functions (which do not contain this prefix). For details, see Functions for File and Directory Operations.
nn::fs::XXX();
// Because errors are handled internally by non-Try functions, you do not need to receive Result values.
result = nn::fs::TryXXX();
if(result.IsFailure())
{
if(result <= nn::fs::ResultNotFound())
{
// The specified path does not exist.
// NOTE: This error is returned when creating a file or directory only if the problem involves an incorrect archive name.
// You do not need to handle this if, by design, it does not occur.
}
else if(result <= nn::fs::ResultAlreadyExists())
{
// The specified path already exists.
// NOTE: This error is not returned when files and directories are deleted.
// You do not need to handle this if, by design, it does not occur.
}
else if(result <= nn::fs::ResultVerificationFailed())
{
// You must delete and recreate this file or directory.
// CAUSE: Corrupted or tampered-with save data.
// NOTE: This state will never be caused by user operations (such as removing a card or turning off the system while data is being written) when there is automatic redundancy.
// This error occurs even by user operations when there is no automatic redundancy.
// If this is not resolved, you must format the save data.
// NOTE: This error is returned when reading a region that has never been written to.
// Be careful after executing the functions nn::fs::TryCreateFile and nn::fs::FileStream::TrySetSize.
}
else if(result <= nn::fs::ResultOperationDenied())
{
// Access was denied for some reason.
// EXAMPLE: You attempted to delete a file that was open elsewhere.
// You attempted to move a file or directory so that it would span archives.
// You attempted to delete the root directory.
// NOTE: You do not need handling for the above situations if, by design, they will not occur.
// But nn::fs::ResultMediaAccessError is returned if failure is due to a bad connection or other hardware factor.
// In such cases, recovery may be possible by retrying, re-inserting the Game Card, restarting the system, or some other action.
}
else if(result <= nn::fs::ResultNotEnoughSpace())
{
// There is no available space in the archive or on the storage media.
// NOTE: This error may occur when creating a file or directory, or changing the file size.
// If this error occurs when you create a file, delete the file because it might be corrupted.
// If this error occurs when you change the size of a file, the file may have grown to the maximum possible size.
}
else
{
// Unexpected error if other than the above
NN_ERR_THROW_FATAL_ALL(result);
}
}
result = nn::fs::TryXXX();
if(result.IsFailure())
{
if(result <= nn::fs::ResultNotFound())
{
if(result <= nn::fs::ResultMediaNotFound())
{
// An SD Card has not been inserted.
// Note: This error is also returned if the SD Card is damaged or if some medium other than an SD Card is inserted.
// In such cases, an insertion event registered by RegisterSdmcInsertedEvent is signaled.
}
else
{
// The specified path does not exist.
// NOTE: This error is returned when creating a file or directory only if the problem involves an incorrect archive name.
// NOTE: Expanded save data can also be accessed from other applications,
// so handling is not required for this error.
}
}
else if(result <= nn::fs::ResultAlreadyExists())
{
// The specified path already exists.
// NOTE: This error is not returned when files and directories are deleted.
// NOTE: Expanded save data can also be accessed from other applications,
// so handling is not required for this error.
}
else if(result <= nn::fs::ResultVerificationFailed())
{
// You must delete and recreate this file or directory.
// CAUSE: Corrupted or tampered-with save data.
// NOTE: If this is not resolved, you need to recreate the expanded save data.
// NOTE: This error is returned when reading a region that has never been written to.
// Be careful after executing the functions nn::fs::TryCreateFile and nn::fs::FileStream::TrySetSize.
}
else if(result <= nn::fs::ResultArchiveInvalidated())
{
// You must remount the archive.
// CAUSE: The SD Card was removed, making the archive invalid.
// NOTE: Close all open files, call the nn::fs::Unmount function, and then remount the archive.
}
else if(result <= nn::fs::ResultOperationDenied())
{
if(result <= nn::fs::ResultWriteProtected())
{
// The SD Card is write-locked.
// NOTE: This error occurs when you write to an SD Card. This does not occur when you simply open a file.
}
else if(result <= nn::fs::ResultMediaAccessError())
{
// This error is only returned when the cause is hardware-related, such as a loose connection.
// In such cases, recovery may be possible by retrying, re-inserting the Game Card, restarting the system, or some other action.
}
else
{
// Access was denied for some reason other than those above.
// EXAMPLES: You attempted to write to a file that is read-only.
// You attempted to delete a file that was open elsewhere.
// You attempted to move a file or directory so that it would span archives.
// You attempted to delete the root directory.
// (Note) Because the content of expanded save data can be modified even by other applications (depending on operations),
// or a user may have spoofed data on the SD card using a PC, this error must always be handled
}
}
else if(result <= nn::fs::ResultNotEnoughSpace())
{
// There is no available space in the archive or on the storage media.
// NOTE: This error may occur when creating a file or directory, or changing the file size.
// If this error occurs when you create a file, delete the file because it might be corrupted.
// If this error occurs when you change the size of a file, the file may have grown to the maximum possible size.
}
else
{
// Unexpected error if other than the above
NN_ERR_THROW_FATAL_ALL(result);
}
}
ResultArchiveInvalidated from the errors that can occur for functions that create and delete expanded save data.ResultBadFormat to formatting the SD card.ResultBadFormat from how manipulating expanded save data files and directories are handled.NN_ERR_THROW_FATAL_ALL.ResultArchiveInvalidated from the errors that can occur when mounting the expanded save data.Result from ResultMediaAccessError to ResultMediaNotFound when a damaged SD Card is inserted.ResultNotFormatted and ResultArchiveInvalidated to error handling when expanded save data is created.ResultOperationDenied is handled when expanded save data is mounted.ResultNotFound from save data error handling.ResultNotEnoughSpace to the errors occurring during file operations.ResultNotFormatted to error handling for expanded save data.CONFIDENTIAL