Closed Bug 931720 Opened 9 years ago Closed 9 years ago

Returning low-level error correctly from nsLocalFile::CopyToNative()

Categories

(Core Graveyard :: File Handling, defect)

All
Linux
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED
mozilla28

People

(Reporter: ishikawa, Assigned: ishikawa)

References

(Blocks 2 open bugs)

Details

Attachments

(1 file, 1 obsolete file)

Returning low-level error correctly from nsLocalFile::CopyToNative()

In trying to fix and analyze the bug Bug 930397 - Failure to handle
error during writing to an almost full file system (TB saving an
attachment/FF downloading)", I noticed that the error value passed to
the routine, FailedDownload() that shows the error dialog, is bogus.
It is NS_ERROR_OUT_OF_MEMORY when the error is actually the failure to
write to a full file system. I would think the routine should have
been passed NS_ERROR_FILE_DISK_FULL instead.

This is a failure of low-level routine not passing the error code
properly so that the upper-level routine can use the error values for
detailed user-friendly error processing (such as error message that
pin points the cause of the error precisely.)

So I analyzed the calling sequence and found that
nsDownload::MoveTempToTarget() failed with NS_ERROR_OUT_OF_MEMORY, and
this error value is passed to FailedDownload().  Bad. The error is bogus!

I found the eventual cause is that |nsLocalFile::CopyToNative| in
mozilla/xpcom/io/nsLocalFileUnix.cpp is not handling error properly
and returned a bogus error value when |PR_Write| failed. A patch that
reports the error properly uploaded in the next message.

 
E.g.: Stack dump and a few interspersed comments :

This is when the failure to save an attachment of happened.

#0  nsDownload::FailDownload (this=this@entry=0x9d95600, 
    aStatus=aStatus@entry=NS_ERROR_OUT_OF_MEMORY, aMessage=aMessage@entry=0x0)
    at /new-hd1/extra/ishikawa/TB-3HG/NEW-COMMSRC/mozilla/toolkit/components/downloads/nsDownloadManager.cpp:3650

    NS_ERROR_OUT_OF_MEMORY in aStatus seems to contain bogus error value.
 
#1  0xb4224b64 in nsDownload::SetState (this=this@entry=0x9d95600, 
    aState=aState@entry=1)
    at /new-hd1/extra/ishikawa/TB-3HG/NEW-COMMSRC/mozilla/toolkit/components/downloads/nsDownloadManager.cpp:2656

    I initially thought     nsDownload::SetState ought to be called with    
    nsIDownloadManager::DOWNLOAD_FAILED:

    But it is called with

    aState=aState@entry=1

    which is DOWNLOAD_FINISHED (Strange???)

    But I need to investigate this part further since, using POP3 for
    TB, the attachment is already in the local folder successfully,
    and maybe this DOWNLOAD_FINISHED may mean that the a copy of the
    attachment alone could be written to a (temporary?) directory
    safely, and has nothing to do with the final saving. This is a
    TODO thing. That the same code path is used by TB (mail client)
    and FF (browser) complicates the terminology quite a bit.

    Back to stack trace, after SetState is called with
    DOWNLOAD_FINISHED, it will execute ExecuteDesiredAction: which
    invokes MoveTempToTarget() and it failed with
    NS_OUT_OF_MEMORY() in my debug session.

Yes, eventually, CopyToNative() is called, and it fails with the bogus error.

    http://mxr.mozilla.org/comm-central/source/mozilla/xpcom/io/nsLocalFileUnix.cpp#718

That is, nsLocalFile::CopyToNative() returns bogus error value when
NS_Write() failed to write the desired number of octets to the
file. It returns NS_ERROR_OUT_OF_MEMORY without bothering to check the
POSIX errno value immediately after the error failed.

PS:
While trying to fix this issue, I needed to map POSIX ENOSPC (No space
left on device) error macro to NS_ERROR_FILE_DISK_FULL, and
such mapping of POSIX errno to NS_ERROR_* macro was done
by NSRESULT_FOR_ERRNO() in mozilla/xpcom/io/nsLocalFile.h
in other parts of mozilla/xpcom/io/nsLocalFileUnix.cpp

But it did not handle ENOSPC, and so I filed a bug
Bug 931703 - Adding ENOSPC and a few other POSIX error macros to
nsresultForErrno()


PPS: when I submit this bugzilla entry, I notice "Bug 191877 	
writing to the file stream is not returning the right error" that was shown as similar to the bug.
That discusses QUOTA exceeded error over NFS mount when a saving of attachment takes place.
This is not a exact dupe of thas error, but
I think the patch in
Bug 931703 - Adding ENOSPC and a few other POSIX error macros to
nsresultForErrno()
might need to handle error code for quota exceeded over NFS mount
(EDQUOT in linux, and this is not part of POSIX if I am not mistaken.)
Of course, whatever routine that handles NFS-stream I/O should
pass this error properly back to the caller as NS_ERROR_FILE_DISK_FULL (since we do not have NFS-specific code in mozilla, it seems.)

It may be that the fix here coupled with the proper extension
in Bug 931703 may help the proper error message in the future.
(The code may be passed back properly to FailedDownload(), but then
it is up to that function to decide what message is shown to the user.)
Blocks: 930397
Depends on: 931703
See Also: → 191877
Attachment #823250 - Flags: review?(ehsan)
Assignee: nobody → ishikawa
Comment on attachment 823250 [details] [diff] [review]
PATCH: returning proper error codes from CopyToNative().

Review of attachment 823250 [details] [diff] [review]:
-----------------------------------------------------------------

I am not the right reviewer here.
Attachment #823250 - Flags: review?(ehsan) → review?(benjamin)
(In reply to :Ehsan Akhgari (needinfo? me!) [Away 10/29-11/6] from comment #2)
> Comment on attachment 823250 [details] [diff] [review]
> PATCH: returning proper error codes from CopyToNative().
...
> I am not the right reviewer here.

Thank you for the reassignment. I will assign the reviewer for related bugzilla entries accordingly.
Blocks: 435025
Comment on attachment 823250 [details] [diff] [review]
PATCH: returning proper error codes from CopyToNative().

Instead of the #if DEBUG abort() please just use

else
  MOZ_ASSERT();

r=me with that change
Attachment #823250 - Flags: review?(benjamin) → review+
Thank you for the review.
I have changed the line to use MOZ_ASSERT(0);

I am going to put checkin-needed keyword.

TIA
Attachment #823250 - Attachment is obsolete: true
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/ed35c291d57e
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla28
Blocks: 936987
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.