Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solving conversion of mails with Swiftmailer #24

Closed
wants to merge 5 commits into from

Conversation

risototh
Copy link
Contributor

This will allow us to convert msg files to eml file, even if the source uses some invalid email addresses or some of the data are missing at all.
Without this, it can fail on any of the headers, and thus prevent the conversion, and it's better to present at least something to user, than nothing.

@hfig
Copy link
Owner

hfig commented Apr 4, 2021

I ... don't like this. You're swallowing all errors, expected or otherwise.

I think the idea, overall, is reasonable -- MAPI to Mime is an imperfect translation and so the implementer can expect that some fidelity is lost. But by omitting "random" fields the we ordinarily convert, you're kind of breaking the contract.

You can verify if an email address is invalid and will throw using the example in the SwiftMailer docs:

$validator = new EmailValidator();
$validator->isValid("example@example.com", new RFCValidation()); //true

So, I'd suggest:

  • Only handle \Swift_RfcComplianceException not \Exception
  • It looks like \Swift_RfcComplianceException is only thrown on setting an address (ie a call to addRecipientHeaders()) or setting the message ID, so don't wrap the dates or body in exception handling
  • The conversion errors should stored and made available to the caller somehow. To be determined how to do this (throw an exception, add an instance method, add an attachment to the converted email)

@risototh
Copy link
Contributor Author

risototh commented Apr 6, 2021

I don't like it too, but obviously, we had problems with the conversions and this was the solution. It wasn't only the problem with the emails, but also with the dates, and even with the body. This all is based on real experience with implementation of msg viewer and tested on client files (170k+ files).
Throwing and exception in the middle of the conversion does not solve anything, as the conversion stops. Only solution that I can see is maybe adding one more parameter, that enables/disabled the throwing of the exceptions, because I don't need them, I need to show at least something, which is way better, than nothing.
What about that solution?

@hfig
Copy link
Owner

hfig commented Apr 10, 2021

I don't have a problem with it not throwing and with the conversion being lossy, but it needs to indicate to the caller that the conversion completed only partly. And, as noted, it needs to only catch the exceptions we're expecting and intentionally swallowing (\Swift_RfcComplianceException)

@risototh
Copy link
Contributor Author

OK, I will try to rewrite it to something more useful, that will control the exceptions.

@risototh
Copy link
Contributor Author

risototh commented Jun 8, 2021

I have implemented the catching of the exceptions on condition. Default behaviour is like previous. The exceptions can be muted, and in that case, all exceptions will be recorded to internal array and can be requested by getter method.
Is it OK now?

@risototh

This comment has been minimized.

@risototh
Copy link
Contributor Author

risototh commented Jun 8, 2021

OK, the formatting is fixed now. I reverted the previous commit and made the adjustments in Sublime, instead of PhpStorm...

@hfig
Copy link
Owner

hfig commented Jun 13, 2021

This is OK mostly. Thanks for your work.

But I do have a quibble mucking with the interface by introducing an optional parameter. I think a reasonable fix would be to make the state of swallowing exceptions or not a property of the factory class. Therefore you call toMime() but the factory determines the parsing behaviour (swallow or throw). If you could:

  • either modify the Hfig\MAPI\Mime\Swiftmailer\Message constructor to add the muteConversionExceptions option OR add a public setter for it.
  • In Hfig\MAPI\Mime\Swiftmailer\Factory add muteConversionExceptions as a parameter to the constructor and a property of the class
  • modify Hfig\MAPI\Mime\Swiftmailer\Factory:: parseMessage() to pass through muteConversionExceptions from the factory

Does that make sense/sound reasonable? You'd now write $messageFactory = new MAPI\MapiMessageFactory(new Swiftmailer\Factory(true)); to swallow conversion exceptions when calling toMime()

@risototh
Copy link
Contributor Author

OK, I will think about it, as I need to pass it somehow to this construction:
$wrappedAttachment = \Hfig\MAPI\Mime\Swiftmailer\Attachment::wrap($attachment);
$content = $wrappedAttachment->toMimeString();

and this calls the Message::wrap($this->embedded_msg)->toMime() internally, so I think, that I will need to add the public method to the Attachment class, and also to the Message class, and set Message->setMuteConversionExceptions() also in the Attachment->toMime() method.

Will this be acceptable?

@hfig
Copy link
Owner

hfig commented Jun 19, 2021

hmm it took me a while to understand what you're saying here because your PR doesn't currently include that functionality (passing the flag through so that it would apply to MSG attachments). At the moment your logic in the PR will just ignore/drop the whole attachment if it has an invalidity.

So you've expanded the scope of things a bit!

But yes you can do any of: change the Attachment default constructor, add methods to Message and Attachment classes or change the signature of their ::wrap() constructors (they aren't what I'd consider part of a public contract).

@hfig
Copy link
Owner

hfig commented Jun 12, 2023

Merged an amended version - PR38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants